Skip to content

Commit

Permalink
CON-9337 csi snapshot resizing (#490)
Browse files Browse the repository at this point in the history
  • Loading branch information
llDrLove authored May 11, 2023
1 parent 12f5d69 commit 2221a95
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 5 deletions.
35 changes: 32 additions & 3 deletions driver/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ const (
// maxVolumesPerDropletErrorMessage is the error message returned by the DO
// API when the per-droplet volume limit would be exceeded.
maxVolumesPerDropletErrorMessage = "cannot attach more than 7 volumes to a single Droplet"

// doneActionStatus is used to determine if a Digital Ocean resize action is completed.
doneActionStatus = "done"
)

var (
Expand Down Expand Up @@ -162,22 +165,28 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
}

contentSource := req.GetVolumeContentSource()
var snapshot *godo.Snapshot
if contentSource != nil && contentSource.GetSnapshot() != nil {
snapshotID := contentSource.GetSnapshot().GetSnapshotId()
if snapshotID == "" {
return nil, status.Error(codes.InvalidArgument, "snapshot ID is empty")
}

// check if the snapshot exist before we continue
_, resp, err := d.snapshots.Get(ctx, snapshotID)
var resp *godo.Response
snapshot, resp, err = d.snapshots.Get(ctx, snapshotID)
if err != nil {
if resp != nil && resp.StatusCode == http.StatusNotFound {
return nil, status.Errorf(codes.NotFound, "snapshot %q does not exist", snapshotID)
}
return nil, err
}
log = log.WithFields(logrus.Fields{
"snapshot_id": snapshotID,
"snapshot_size_giga_bytes": snapshot.SizeGigaBytes,
})
log.Info("using snapshot as volume source")

log.WithField("snapshot_id", snapshotID).Info("using snapshot as volume source")
volumeReq.SnapshotID = snapshotID
}

Expand All @@ -191,6 +200,26 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
return nil, status.Error(codes.Internal, err.Error())
}

if snapshot != nil && volumeReq.SizeGigaBytes > int64(snapshot.SizeGigaBytes) && volumeReq.SizeGigaBytes > 1 {
log.Info("resizing volume because its requested size is larger than the size of the backing snapshot")
action, _, err := d.storageActions.Resize(ctx, vol.ID, int(volumeReq.SizeGigaBytes), volumeReq.Region)
if err != nil {
return nil, status.Errorf(codes.Internal, "cannot resize volume %s: %s", vol.ID, err.Error())
}
log = log.WithFields(logrus.Fields{
"resized_from": int(snapshot.SizeGigaBytes),
"resized_to": int(volumeReq.SizeGigaBytes),
})
if action != nil && action.Status != doneActionStatus {
log = logWithAction(log, action)
log.Info("waiting until volume is resized")
if err := d.waitAction(ctx, log, vol.ID, action.ID); err != nil {
return nil, status.Errorf(codes.Internal, "failed waiting on action ID %d for volume ID %s to get resized: %s", action.ID, vol.ID, err)
}
}
log.Info("resize completed")
}

resp := &csi.CreateVolumeResponse{
Volume: &csi.Volume{
VolumeId: vol.ID,
Expand Down Expand Up @@ -1023,7 +1052,7 @@ func (d *Driver) waitAction(ctx context.Context, log *logrus.Entry, volumeID str
}
log = log.WithField("action_status", action.Status)

if action.Status == godo.ActionCompleted {
if action.Status == godo.ActionCompleted || action.Status == doneActionStatus {
log.Info("action completed")
return true, nil
}
Expand Down
19 changes: 19 additions & 0 deletions driver/node.go

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

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ require (
google.golang.org/grpc v1.51.0
gotest.tools/v3 v3.4.0
k8s.io/apimachinery v0.27.1
k8s.io/klog/v2 v2.90.1
k8s.io/mount-utils v0.27.1
k8s.io/utils v0.0.0-20230209194617-a36077c30491
)
Expand Down Expand Up @@ -53,7 +54,6 @@ require (
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.90.1 // indirect
)

replace k8s.io/api => k8s.io/api v0.27.1
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/testdrivers/1.27.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ DriverInfo:
fsGroup: true
volumeMountGroup: false
exec: true
snapshotDataSource: false
snapshotDataSource: true
pvcDataSource: false
multipods: true
RWX: false
Expand Down

0 comments on commit 2221a95

Please sign in to comment.