Skip to content

Commit

Permalink
Don't wait for the snapshot to be completed
Browse files Browse the repository at this point in the history
  • Loading branch information
tsmetana authored and Cheng Pan committed Feb 18, 2019
1 parent 9d04b63 commit c1f58aa
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 55 deletions.
64 changes: 10 additions & 54 deletions pkg/cloud/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"context"
"errors"
"fmt"
"math"
"time"

"github.com/aws/aws-sdk-go/aws"
Expand Down Expand Up @@ -122,6 +121,7 @@ type Snapshot struct {
SourceVolumeID string
Size int64
CreationTime time.Time
ReadyToUse bool
}

// SnapshotOptions represents parameters to create an EBS volume
Expand Down Expand Up @@ -509,10 +509,6 @@ func (c *cloud) CreateSnapshot(ctx context.Context, volumeID string, snapshotOpt
if res == nil {
return nil, fmt.Errorf("nil CreateSnapshotResponse")
}
err = c.waitForSnapshotCreate(ctx, res.SnapshotId)
if err != nil {
return nil, err
}

return c.ec2SnapshotResponseToStruct(res), nil
}
Expand Down Expand Up @@ -554,12 +550,19 @@ func (c *cloud) ec2SnapshotResponseToStruct(ec2Snapshot *ec2.Snapshot) *Snapshot
return nil
}
snapshotSize := util.GiBToBytes(aws.Int64Value(ec2Snapshot.VolumeSize))
return &Snapshot{
snapshot := &Snapshot{
SnapshotID: aws.StringValue(ec2Snapshot.SnapshotId),
SourceVolumeID: aws.StringValue(ec2Snapshot.VolumeId),
Size: snapshotSize,
CreationTime: aws.TimeValue(ec2Snapshot.StartTime),
}
if aws.StringValue(ec2Snapshot.State) == "completed" {
snapshot.ReadyToUse = true
} else {
snapshot.ReadyToUse = false
}

return snapshot
}

func (c *cloud) getVolume(ctx context.Context, request *ec2.DescribeVolumesInput) (*ec2.Volume, error) {
Expand Down Expand Up @@ -669,14 +672,7 @@ func (c *cloud) waitForVolume(ctx context.Context, volumeID string) error {
return true, err
}
if vol.State != nil {
switch *vol.State {
case "available":
return true, nil
case "creating":
return false, nil
default:
return true, fmt.Errorf("unexpected state for volume %s: %q", volumeID, *vol.State)
}
return *vol.State == "available", nil
}
return false, nil
})
Expand Down Expand Up @@ -708,43 +704,3 @@ func isAWSErrorSnapshotNotFound(err error) bool {

return false
}

func (c *cloud) waitForSnapshotCreate(ctx context.Context, snapshotID *string) error {
// This should give about 1 minute maximal interval
backoff := wait.Backoff{
Duration: 1 * time.Second,
Factor: 1.5,
Steps: 10,
}
request := &ec2.DescribeSnapshotsInput{
SnapshotIds: []*string{
snapshotID,
},
}

conditionFunc := func() (done bool, err error) {
snapshot, err := c.getSnapshot(ctx, request)
if err != nil {
return true, err
}
if snapshot.State != nil {
switch *snapshot.State {
case "completed":
return true, nil
case "pending":
return false, nil
default:
return true, fmt.Errorf("unexpected State of newly created AWS EBS snapshot %v: %q", snapshotID, *snapshot.State)
}
}
return false, nil
}

// Truncated exponential backoff: if the exponential backoff times-out, just keep polling using the longest interval
err := wait.ExponentialBackoff(backoff, conditionFunc)
if err == wait.ErrWaitTimeout {
timeout := time.Duration(backoff.Duration.Seconds() * math.Pow(backoff.Factor, float64(backoff.Steps)))
err = wait.PollInfinite(timeout*time.Second, conditionFunc)
}
return err
}
2 changes: 1 addition & 1 deletion pkg/driver/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ func newCreateSnapshotResponse(snapshot *cloud.Snapshot) (*csi.CreateSnapshotRes
SourceVolumeId: snapshot.SourceVolumeID,
SizeBytes: snapshot.Size,
CreationTime: ts,
ReadyToUse: true, // In AWS it's eiter this or error
ReadyToUse: snapshot.ReadyToUse,
},
}, nil
}

0 comments on commit c1f58aa

Please sign in to comment.