Skip to content

Commit 6bb78c8

Browse files
committed
initial commit for gp3 migration.
1 parent dc9a5b1 commit 6bb78c8

File tree

9 files changed

+147
-56
lines changed

9 files changed

+147
-56
lines changed

go.mod

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
module github.com/zalando/postgres-operator
22

3-
go 1.14
3+
go 1.15
44

55
require (
6-
github.com/aws/aws-sdk-go v1.35.15
6+
github.com/aws/aws-sdk-go v1.36.2
77
github.com/lib/pq v1.8.0
88
github.com/motomux/pretty v0.0.0-20161209205251-b2aad2c9a95d
99
github.com/r3labs/diff v1.1.0
1010
github.com/sirupsen/logrus v1.7.0
1111
github.com/stretchr/testify v1.5.1
1212
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
13-
golang.org/x/tools v0.0.0-20201121010211-780cb80bd7fb // indirect
13+
golang.org/x/mod v0.4.0 // indirect
14+
golang.org/x/tools v0.0.0-20201206230334-368bee879bfd // indirect
1415
gopkg.in/yaml.v2 v2.2.8
1516
k8s.io/api v0.19.3
1617
k8s.io/apiextensions-apiserver v0.19.3

go.sum

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo
4444
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
4545
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
4646
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
47-
github.com/aws/aws-sdk-go v1.35.15 h1:JdQNM8hJe+9N9xP53S54NDmX8GCaZn8CCJ4LBHfom4U=
48-
github.com/aws/aws-sdk-go v1.35.15/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
47+
github.com/aws/aws-sdk-go v1.36.2 h1:UAeFPct+jHqWM+tgiqDrC9/sfbWj6wkcvpsJ+zdcsvA=
48+
github.com/aws/aws-sdk-go v1.36.2/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
4949
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
5050
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
5151
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
@@ -403,6 +403,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
403403
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
404404
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
405405
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
406+
golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
407+
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
406408
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
407409
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
408410
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -423,12 +425,13 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
423425
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
424426
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
425427
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
426-
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
427428
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
428429
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
429430
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
430431
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
431432
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
433+
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
434+
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
432435
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
433436
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
434437
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -505,8 +508,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
505508
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
506509
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
507510
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
508-
golang.org/x/tools v0.0.0-20201121010211-780cb80bd7fb h1:z5+u0pkAUPUWd3taoTialQ2JAMo4Wo1Z3L25U4ZV9r0=
509-
golang.org/x/tools v0.0.0-20201121010211-780cb80bd7fb/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
511+
golang.org/x/tools v0.0.0-20201206230334-368bee879bfd h1:EqFvKLTxjH6gEy2baWxX2AgJwZkBIDIcZFYcoYlI9RA=
512+
golang.org/x/tools v0.0.0-20201206230334-368bee879bfd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
510513
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
511514
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
512515
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=

pkg/apis/acid.zalan.do/v1/postgresql_type.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,11 @@ type Volume struct {
115115
Size string `json:"size"`
116116
StorageClass string `json:"storageClass"`
117117
SubPath string `json:"subPath,omitempty"`
118+
Iops *int64 `json:"iops,omitempty"`
119+
Throughput *int64 `json:"throughput,omitempty"`
118120
}
119121

122+
// AdditionalVolume specs additional optional volumes for statefulset
120123
type AdditionalVolume struct {
121124
Name string `json:"name"`
122125
MountPath string `json:"mountPath"`
@@ -156,11 +159,12 @@ type Patroni struct {
156159
SynchronousModeStrict bool `json:"synchronous_mode_strict"`
157160
}
158161

159-
//StandbyCluster
162+
// StandbyDescription contains s3 wal path
160163
type StandbyDescription struct {
161164
S3WalPath string `json:"s3_wal_path,omitempty"`
162165
}
163166

167+
// TLSDescription specs TLS properties
164168
type TLSDescription struct {
165169
SecretName string `json:"secretName,omitempty"`
166170
CertificateFile string `json:"certificateFile,omitempty"`
@@ -198,7 +202,7 @@ type PostgresStatus struct {
198202
PostgresClusterStatus string `json:"PostgresClusterStatus"`
199203
}
200204

201-
// Options for connection pooler
205+
// ConnectionPooler Options for connection pooler
202206
//
203207
// TODO: prepared snippets of configuration, one can choose via type, e.g.
204208
// pgbouncer-large (with higher resources) or odyssey-small (with smaller

pkg/cluster/cluster.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/zalando/postgres-operator/pkg/util/patroni"
2626
"github.com/zalando/postgres-operator/pkg/util/teams"
2727
"github.com/zalando/postgres-operator/pkg/util/users"
28+
"github.com/zalando/postgres-operator/pkg/util/volumes"
2829
appsv1 "k8s.io/api/apps/v1"
2930
v1 "k8s.io/api/core/v1"
3031
policybeta1 "k8s.io/api/policy/v1beta1"
@@ -64,6 +65,14 @@ type kubeResources struct {
6465
//PVCs are treated separately
6566
}
6667

68+
type EBSVolume struct {
69+
volumeId string
70+
volumeType string
71+
size int64
72+
iops int32
73+
throughput int32
74+
}
75+
6776
// Cluster describes postgresql cluster
6877
type Cluster struct {
6978
kubeResources
@@ -89,7 +98,10 @@ type Cluster struct {
8998
processMu sync.RWMutex // protects the current operation for reporting, no need to hold the master mutex
9099
specMu sync.RWMutex // protects the spec for reporting, no need to hold the master mutex
91100
ConnectionPooler map[PostgresRole]*ConnectionPoolerObjects
101+
EBSVolumes map[string]EBSVolume
102+
VolumeResizer volumes.VolumeResizer
92103
}
104+
93105
type compareStatefulsetResult struct {
94106
match bool
95107
replace bool
@@ -134,6 +146,11 @@ func New(cfg Config, kubeClient k8sutil.KubernetesClient, pgSpec acidv1.Postgres
134146
cluster.oauthTokenGetter = newSecretOauthTokenGetter(&kubeClient, cfg.OpConfig.OAuthTokenSecretName)
135147
cluster.patroni = patroni.New(cluster.logger)
136148
cluster.eventRecorder = eventRecorder
149+
150+
if cfg.OpConfig.StorageResizeMode != "pvc" {
151+
cluster.VolumeResizer = &volumes.EBSVolumeResizer{AWSRegion: cfg.OpConfig.AWSRegion}
152+
}
153+
137154
return cluster
138155
}
139156

pkg/cluster/sync.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"github.com/zalando/postgres-operator/pkg/util"
1212
"github.com/zalando/postgres-operator/pkg/util/constants"
1313
"github.com/zalando/postgres-operator/pkg/util/k8sutil"
14-
"github.com/zalando/postgres-operator/pkg/util/volumes"
1514
appsv1 "k8s.io/api/apps/v1"
1615
batchv1beta1 "k8s.io/api/batch/v1beta1"
1716
v1 "k8s.io/api/core/v1"
@@ -55,7 +54,15 @@ func (c *Cluster) Sync(newSpec *acidv1.Postgresql) error {
5554
}
5655

5756
c.logger.Debugf("syncing volumes using %q storage resize mode", c.OpConfig.StorageResizeMode)
58-
if c.OpConfig.StorageResizeMode == "pvc" {
57+
58+
if c.OpConfig.StorageResizeMode == "mixed" {
59+
60+
// resize pvc to adjust filesystem size until better K8s support
61+
if err = c.syncVolumeClaims(); err != nil {
62+
err = fmt.Errorf("could not sync persistent volume claims: %v", err)
63+
return err
64+
}
65+
} else if c.OpConfig.StorageResizeMode == "pvc" {
5966
if err = c.syncVolumeClaims(); err != nil {
6067
err = fmt.Errorf("could not sync persistent volume claims: %v", err)
6168
return err
@@ -599,7 +606,8 @@ func (c *Cluster) syncVolumes() error {
599606
if !act {
600607
return nil
601608
}
602-
if err := c.resizeVolumes(c.Spec.Volume, []volumes.VolumeResizer{&volumes.EBSVolumeResizer{AWSRegion: c.OpConfig.AWSRegion}}); err != nil {
609+
610+
if err := c.resizeVolumes(); err != nil {
603611
return fmt.Errorf("could not sync volumes: %v", err)
604612
}
605613

pkg/cluster/volumes.go

Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"github.com/zalando/postgres-operator/pkg/util"
1616
"github.com/zalando/postgres-operator/pkg/util/constants"
1717
"github.com/zalando/postgres-operator/pkg/util/filesystems"
18-
"github.com/zalando/postgres-operator/pkg/util/volumes"
1918
)
2019

2120
func (c *Cluster) listPersistentVolumeClaims() ([]v1.PersistentVolumeClaim, error) {
@@ -119,19 +118,26 @@ func (c *Cluster) listPersistentVolumes() ([]*v1.PersistentVolume, error) {
119118
}
120119

121120
// resizeVolumes resize persistent volumes compatible with the given resizer interface
122-
func (c *Cluster) resizeVolumes(newVolume acidv1.Volume, resizers []volumes.VolumeResizer) error {
123-
c.setProcessName("resizing volumes")
121+
func (c *Cluster) resizeVolumes() error {
122+
if c.VolumeResizer == nil {
123+
return fmt.Errorf("no volume resizer set for EBS volume handling")
124+
}
125+
126+
c.setProcessName("resizing EBS volumes")
124127

128+
resizer := c.VolumeResizer
125129
var totalIncompatible int
126130

127-
newQuantity, err := resource.ParseQuantity(newVolume.Size)
131+
newQuantity, err := resource.ParseQuantity(c.Spec.Volume.Size)
128132
if err != nil {
129133
return fmt.Errorf("could not parse volume size: %v", err)
130134
}
131-
pvs, newSize, err := c.listVolumesWithManifestSize(newVolume)
135+
136+
pvs, newSize, err := c.listVolumesWithManifestSize(c.Spec.Volume)
132137
if err != nil {
133138
return fmt.Errorf("could not list persistent volumes: %v", err)
134139
}
140+
135141
for _, pv := range pvs {
136142
volumeSize := quantityToGigabyte(pv.Spec.Capacity[v1.ResourceStorage])
137143
if volumeSize >= newSize {
@@ -141,43 +147,43 @@ func (c *Cluster) resizeVolumes(newVolume acidv1.Volume, resizers []volumes.Volu
141147
continue
142148
}
143149
compatible := false
144-
for _, resizer := range resizers {
145-
if !resizer.VolumeBelongsToProvider(pv) {
146-
continue
147-
}
148-
compatible = true
149-
if !resizer.IsConnectedToProvider() {
150-
err := resizer.ConnectToProvider()
151-
if err != nil {
152-
return fmt.Errorf("could not connect to the volume provider: %v", err)
153-
}
154-
defer func() {
155-
if err := resizer.DisconnectFromProvider(); err != nil {
156-
c.logger.Errorf("%v", err)
157-
}
158-
}()
159-
}
160-
awsVolumeID, err := resizer.GetProviderVolumeID(pv)
150+
151+
if !resizer.VolumeBelongsToProvider(pv) {
152+
continue
153+
}
154+
compatible = true
155+
if !resizer.IsConnectedToProvider() {
156+
err := resizer.ConnectToProvider()
161157
if err != nil {
162-
return err
163-
}
164-
c.logger.Debugf("updating persistent volume %q to %d", pv.Name, newSize)
165-
if err := resizer.ResizeVolume(awsVolumeID, newSize); err != nil {
166-
return fmt.Errorf("could not resize EBS volume %q: %v", awsVolumeID, err)
167-
}
168-
c.logger.Debugf("resizing the filesystem on the volume %q", pv.Name)
169-
podName := getPodNameFromPersistentVolume(pv)
170-
if err := c.resizePostgresFilesystem(podName, []filesystems.FilesystemResizer{&filesystems.Ext234Resize{}}); err != nil {
171-
return fmt.Errorf("could not resize the filesystem on pod %q: %v", podName, err)
158+
return fmt.Errorf("could not connect to the volume provider: %v", err)
172159
}
173-
c.logger.Debugf("filesystem resize successful on volume %q", pv.Name)
174-
pv.Spec.Capacity[v1.ResourceStorage] = newQuantity
175-
c.logger.Debugf("updating persistent volume definition for volume %q", pv.Name)
176-
if _, err := c.KubeClient.PersistentVolumes().Update(context.TODO(), pv, metav1.UpdateOptions{}); err != nil {
177-
return fmt.Errorf("could not update persistent volume: %q", err)
178-
}
179-
c.logger.Debugf("successfully updated persistent volume %q", pv.Name)
160+
defer func() {
161+
if err := resizer.DisconnectFromProvider(); err != nil {
162+
c.logger.Errorf("%v", err)
163+
}
164+
}()
180165
}
166+
awsVolumeID, err := resizer.GetProviderVolumeID(pv)
167+
if err != nil {
168+
return err
169+
}
170+
c.logger.Debugf("updating persistent volume %q to %d", pv.Name, newSize)
171+
if err := resizer.ResizeVolume(awsVolumeID, newSize); err != nil {
172+
return fmt.Errorf("could not resize EBS volume %q: %v", awsVolumeID, err)
173+
}
174+
c.logger.Debugf("resizing the filesystem on the volume %q", pv.Name)
175+
podName := getPodNameFromPersistentVolume(pv)
176+
if err := c.resizePostgresFilesystem(podName, []filesystems.FilesystemResizer{&filesystems.Ext234Resize{}}); err != nil {
177+
return fmt.Errorf("could not resize the filesystem on pod %q: %v", podName, err)
178+
}
179+
c.logger.Debugf("filesystem resize successful on volume %q", pv.Name)
180+
pv.Spec.Capacity[v1.ResourceStorage] = newQuantity
181+
c.logger.Debugf("updating persistent volume definition for volume %q", pv.Name)
182+
if _, err := c.KubeClient.PersistentVolumes().Update(context.TODO(), pv, metav1.UpdateOptions{}); err != nil {
183+
return fmt.Errorf("could not update persistent volume: %q", err)
184+
}
185+
c.logger.Debugf("successfully updated persistent volume %q", pv.Name)
186+
181187
if !compatible {
182188
c.logger.Warningf("volume %q is incompatible with all available resizing providers, consider switching storage_resize_mode to pvc or off", pv.Name)
183189
totalIncompatible++

pkg/util/config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ type Config struct {
198198
SetMemoryRequestToLimit bool `name:"set_memory_request_to_limit" default:"false"`
199199
EnableLazySpiloUpgrade bool `name:"enable_lazy_spilo_upgrade" default:"false"`
200200
EnablePgVersionEnvVar bool `name:"enable_pgversion_env_var" default:"false"`
201+
EnableEBSGp3Migration bool `name:"enable_ebs_gp3_migration" default:"false"`
202+
EnableEBSGp3MaxSize int32 `name:"enable_ebs_gp3_max_size" default:"1000"`
201203
}
202204

203205
// MustMarshal marshals the config or panics

pkg/util/volumes/ebs.go

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"github.com/aws/aws-sdk-go/aws"
88
"github.com/aws/aws-sdk-go/aws/session"
99
"github.com/aws/aws-sdk-go/service/ec2"
10-
"k8s.io/api/core/v1"
10+
v1 "k8s.io/api/core/v1"
1111

1212
"github.com/zalando/postgres-operator/pkg/util/constants"
1313
"github.com/zalando/postgres-operator/pkg/util/retryutil"
@@ -102,6 +102,57 @@ func (c *EBSVolumeResizer) ResizeVolume(volumeID string, newSize int64) error {
102102
})
103103
}
104104

105+
// ModifyVolume Modify EBS volume
106+
func (c *EBSVolumeResizer) ModifyVolume(volumeID string, newType string, newSize int64, iops int64, throughput int64) error {
107+
/* first check if the volume is already of a requested size */
108+
volumeOutput, err := c.connection.DescribeVolumes(&ec2.DescribeVolumesInput{VolumeIds: []*string{&volumeID}})
109+
if err != nil {
110+
return fmt.Errorf("could not get information about the volume: %v", err)
111+
}
112+
vol := volumeOutput.Volumes[0]
113+
if *vol.VolumeId != volumeID {
114+
return fmt.Errorf("describe volume %q returned information about a non-matching volume %q", volumeID, *vol.VolumeId)
115+
}
116+
if *vol.Size == newSize {
117+
// nothing to do
118+
return nil
119+
}
120+
121+
input := ec2.ModifyVolumeInput{Size: &newSize, VolumeId: &volumeID, VolumeType: &newType, Iops: &iops, Throughput: &throughput}
122+
output, err := c.connection.ModifyVolume(&input)
123+
if err != nil {
124+
return fmt.Errorf("could not modify persistent volume: %v", err)
125+
}
126+
127+
state := *output.VolumeModification.ModificationState
128+
if state == constants.EBSVolumeStateFailed {
129+
return fmt.Errorf("could not modify persistent volume %q: modification state failed", volumeID)
130+
}
131+
if state == "" {
132+
return fmt.Errorf("received empty modification status")
133+
}
134+
if state == constants.EBSVolumeStateOptimizing || state == constants.EBSVolumeStateCompleted {
135+
return nil
136+
}
137+
// wait until the volume reaches the "optimizing" or "completed" state
138+
in := ec2.DescribeVolumesModificationsInput{VolumeIds: []*string{&volumeID}}
139+
return retryutil.Retry(constants.EBSVolumeResizeWaitInterval, constants.EBSVolumeResizeWaitTimeout,
140+
func() (bool, error) {
141+
out, err := c.connection.DescribeVolumesModifications(&in)
142+
if err != nil {
143+
return false, fmt.Errorf("could not describe volume modification: %v", err)
144+
}
145+
if len(out.VolumesModifications) != 1 {
146+
return false, fmt.Errorf("describe volume modification didn't return one record for volume %q", volumeID)
147+
}
148+
if *out.VolumesModifications[0].VolumeId != volumeID {
149+
return false, fmt.Errorf("non-matching volume id when describing modifications: %q is different from %q",
150+
*out.VolumesModifications[0].VolumeId, volumeID)
151+
}
152+
return *out.VolumesModifications[0].ModificationState != constants.EBSVolumeStateModifying, nil
153+
})
154+
}
155+
105156
// DisconnectFromProvider closes connection to the EC2 instance
106157
func (c *EBSVolumeResizer) DisconnectFromProvider() error {
107158
c.connection = nil

pkg/util/volumes/volumes.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package volumes
22

3-
import (
4-
"k8s.io/api/core/v1"
5-
)
3+
import v1 "k8s.io/api/core/v1"
64

75
// VolumeResizer defines the set of methods used to implememnt provider-specific resizing of persistent volumes.
86
type VolumeResizer interface {
@@ -11,5 +9,6 @@ type VolumeResizer interface {
119
VolumeBelongsToProvider(pv *v1.PersistentVolume) bool
1210
GetProviderVolumeID(pv *v1.PersistentVolume) (string, error)
1311
ResizeVolume(providerVolumeID string, newSize int64) error
12+
ModifyVolume(providerVolumeID string, newType string, newSize int64, iops int64, throughput int64) error
1413
DisconnectFromProvider() error
1514
}

0 commit comments

Comments
 (0)