Skip to content

Commit

Permalink
Merge 1f71aa1 into 27290b1
Browse files Browse the repository at this point in the history
  • Loading branch information
akutz committed Oct 18, 2015
2 parents 27290b1 + 1f71aa1 commit eb12548
Show file tree
Hide file tree
Showing 6 changed files with 587 additions and 359 deletions.
83 changes: 69 additions & 14 deletions core/errors/errors.go
Expand Up @@ -73,6 +73,10 @@ const (
// ErrCodeLocalVolumeMaps is the error code for when there is an error
// discovering local volume mappings.
ErrCodeLocalVolumeMaps

// ErrCodeRunAsyncFromVolume is the error code for when an asynchronous
// create volume is received.
ErrCodeRunAsyncFromVolume
)

var (
Expand Down Expand Up @@ -136,6 +140,10 @@ var (
// ErrLocalVolumeMaps is the error for when there is an error
// discovering local volume mappings.
ErrLocalVolumeMaps = ErrRexRay(ErrCodeLocalVolumeMaps)

// ErrRunAsyncFromVolume is the error for when an asynchronous
// create volume is received.
ErrRunAsyncFromVolume = ErrRexRay(ErrCodeRunAsyncFromVolume)
)

// RexRayErr is the default error type for REX-Ray errors.
Expand All @@ -151,8 +159,38 @@ func ErrRexRay(code RexRayErrCode) *RexRayErr {
// Error returns the string version of the error code.
func (e *RexRayErr) Error() string {
switch e.Code {
case ErrCodeNoOSDetected:
return "no OS detected"
case ErrCodeNoOSDetected,
ErrCodeNoOSDrivers,
ErrCodeNoVolumeDrivers,
ErrCodeNoStorageDrivers,
ErrCodeNoVolumesReturned:
return e.errorNo()
case ErrCodeDriverBlockDeviceDiscovery,
ErrCodeDriverInstanceDiscovery,
ErrCodeDriverVolumeDiscovery,
ErrCodeDriverSnapshotDiscovery:
return e.errorFailed()
case ErrCodeMultipleDriversDetected,
ErrCodeMultipleVolumesReturned:
return e.errorMulitple()
case ErrCodeUnknownOS,
ErrCodeUnknownFileSystem:
return e.errorUnknown()
case ErrCodeMissingVolumeID:
return "missing volume ID"
case ErrCodeLocalVolumeMaps:
return "getting local volume mounts"
case ErrCodeRunAsyncFromVolume:
return "cannot create volume from volume and run asynchronously"
case ErrCodeNotImplemented:
return "not implemented"
default:
return "unknown error"
}
}

func (e *RexRayErr) errorFailed() string {
switch e.Code {
case ErrCodeDriverBlockDeviceDiscovery:
return "driver block device discovery failed"
case ErrCodeDriverInstanceDiscovery:
Expand All @@ -161,28 +199,45 @@ func (e *RexRayErr) Error() string {
return "driver volume discovery failed"
case ErrCodeDriverSnapshotDiscovery:
return "driver snapshot discovery failed"
case ErrCodeMultipleDriversDetected:
return "multiple drivers detected"
default:
return "unknown error"
}
}

func (e *RexRayErr) errorNo() string {
switch e.Code {
case ErrCodeNoOSDetected:
return "no OS detected"
case ErrCodeNoOSDrivers:
return "no OS drivers initialized"
case ErrCodeNoVolumeDrivers:
return "no volume drivers initialized"
case ErrCodeNoStorageDrivers:
return "no storage drivers initialized"
case ErrCodeNotImplemented:
return "not implemented"
case ErrCodeNoVolumesReturned:
return "no Volumes returned"
default:
return "unknown error"
}
}

func (e *RexRayErr) errorMulitple() string {
switch e.Code {
case ErrCodeMultipleDriversDetected:
return "multiple drivers detected"
case ErrCodeMultipleVolumesReturned:
return "multiple volumes returned"
default:
return "unknown error"
}
}

func (e *RexRayErr) errorUnknown() string {
switch e.Code {
case ErrCodeUnknownOS:
return "unknown OS"
case ErrCodeUnknownFileSystem:
return "unknown file system"
case ErrCodeMissingVolumeID:
return "missing volume ID"
case ErrCodeMultipleVolumesReturned:
return "multiple volumes returned"
case ErrCodeNoVolumesReturned:
return "no Volumes returned"
case ErrCodeLocalVolumeMaps:
return "getting local volume mounts"
default:
return "unknown error"
}
Expand Down
118 changes: 79 additions & 39 deletions drivers/storage/ec2/ec2.go
Expand Up @@ -393,34 +393,26 @@ func (d *driver) CreateVolume(

func (d *driver) createVolume(
runAsync bool, volumeName, volumeID, snapshotID, volumeType string,
IOPS, size int64, availabilityZone string) (*ec2.CreateVolumeResp, error) {
IOPS, size int64,
availabilityZone string) (*ec2.CreateVolumeResp, error) {

if volumeID != "" && runAsync {
return &ec2.CreateVolumeResp{},
errors.New("Cannot create volume from volume and run asynchronously")
return &ec2.CreateVolumeResp{}, errors.ErrRunAsyncFromVolume
}

server, err := d.getInstance()
if err != nil {
var err error

var server ec2.Instance
if server, err = d.getInstance(); err != nil {
return &ec2.CreateVolumeResp{}, err
}

var snapshot *core.Snapshot
if volumeID != "" {
snapshotInt, err := d.CreateSnapshot(
true, fmt.Sprintf("temp-%v", volumeID),
volumeID, "created for createVolume")

if err != nil {
return &ec2.CreateVolumeResp{}, err
}
snapshot = snapshotInt[0]
snapshotID = snapshot.SnapshotID
if snapshotID, err = d.createVolumeCreateSnapshot(
volumeID, snapshotID); err != nil {
return &ec2.CreateVolumeResp{}, err
}

if availabilityZone == "" {
availabilityZone = server.AvailabilityZone
}
d.createVolumeEnsureAvailabilityZone(&availabilityZone, &server)

options := &ec2.CreateVolume{
Size: size,
Expand All @@ -429,7 +421,48 @@ func (d *driver) createVolume(
VolumeType: volumeType,
IOPS: IOPS,
}
resp := &ec2.CreateVolumeResp{}

var resp *ec2.CreateVolumeResp
if resp, err = d.createVolumeCreateVolume(options); err != nil {
return &ec2.CreateVolumeResp{}, err
}

if err = d.createVolumeCreateTags(volumeName, resp); err != nil {
return &ec2.CreateVolumeResp{}, err
}

if err = d.createVolumeWait(
runAsync, snapshotID, volumeID, resp); err != nil {
return &ec2.CreateVolumeResp{}, err
}

return resp, nil
}

func (d *driver) createVolumeCreateSnapshot(
volumeID string, snapshotID string) (string, error) {

var err error
var snapshots []*core.Snapshot

if snapshots, err = d.CreateSnapshot(
true, fmt.Sprintf("temp-%v", volumeID),
volumeID, "created for createVolume"); err != nil {
return "", err
}

return snapshots[0].SnapshotID, nil
}

func (d *driver) createVolumeEnsureAvailabilityZone(
availabilityZone *string, server *ec2.Instance) {
if *availabilityZone == "" {
*availabilityZone = server.AvailabilityZone
}
}

func (d *driver) createVolumeCreateVolume(
options *ec2.CreateVolume) (resp *ec2.CreateVolumeResp, err error) {
for {
resp, err = d.ec2Instance.CreateVolume(options)
if err != nil {
Expand All @@ -438,35 +471,42 @@ func (d *driver) createVolume(
time.Sleep(1 * time.Second)
continue
}
return &ec2.CreateVolumeResp{}, err
return nil, err
}
break
}
return
}

if volumeName != "" {
_, err := d.ec2Instance.CreateTags(
[]string{resp.VolumeId}, []ec2.Tag{{"Name", volumeName}})
if err != nil {
return &ec2.CreateVolumeResp{}, err
}
func (d *driver) createVolumeCreateTags(
volumeName string, resp *ec2.CreateVolumeResp) (err error) {
if volumeName == "" {
return
}
_, err = d.ec2Instance.CreateTags(
[]string{resp.VolumeId}, []ec2.Tag{{"Name", volumeName}})

if !runAsync {
log.Println("Waiting for volume creation to complete")
err = d.waitVolumeComplete(resp.VolumeId)
if err != nil {
return &ec2.CreateVolumeResp{}, err
}
return
}

if volumeID != "" {
err := d.RemoveSnapshot(snapshotID)
if err != nil {
return &ec2.CreateVolumeResp{}, err
}
func (d *driver) createVolumeWait(
runAsync bool, snapshotID, volumeID string,
resp *ec2.CreateVolumeResp) (err error) {
if runAsync {
return
}
log.Println("Waiting for volume creation to complete")
if err = d.waitVolumeComplete(resp.VolumeId); err != nil {
return
}

if volumeID != "" {
if err = d.RemoveSnapshot(snapshotID); err != nil {
return
}
}

return resp, nil
return
}

func (d *driver) getVolume(
Expand Down

0 comments on commit eb12548

Please sign in to comment.