diff --git a/drivers/storage/rackspace/executor/rackspace_executor.go b/drivers/storage/rackspace/executor/rackspace_executor.go deleted file mode 100644 index f313c6f6..00000000 --- a/drivers/storage/rackspace/executor/rackspace_executor.go +++ /dev/null @@ -1,111 +0,0 @@ -// +build none - -package executor - -import ( - "io/ioutil" - "os/exec" - "regexp" - "strings" - - gofig "github.com/akutz/gofig/types" - "github.com/akutz/goof" - - "github.com/codedellemc/libstorage/api/registry" - "github.com/codedellemc/libstorage/api/types" - "github.com/codedellemc/libstorage/drivers/storage/rackspace" -) - -// driver is the storage executor for the VFS storage driver. -type driver struct { - config gofig.Config -} - -func init() { - registry.RegisterStorageExecutor(rackspace.Name, newDriver) -} - -func newDriver() types.StorageExecutor { - return &driver{} -} - -func (d *driver) Init(ctx types.Context, config gofig.Config) error { - d.config = config - return nil -} - -func (d *driver) Name() string { - return rackspace.Name -} - -// InstanceID returns the local instance ID for the test -func InstanceID(config gofig.Config) (*types.InstanceID, error) { - d := newDriver() - d.Init(nil, config) - return d.InstanceID(nil, nil) -} - -// InstanceID returns the aws instance configuration -func (d *driver) InstanceID( - ctx types.Context, - opts types.Store) (*types.InstanceID, error) { - cmd := exec.Command("xenstore-read", "name") - cmd.Env = d.config.EnvVars() - cmdOut, err := cmd.Output() - if err != nil { - return nil, - goof.WithError("problem getting InstanceID", err) - } - - instanceID := strings.Replace(string(cmdOut), "\n", "", -1) - - validInstanceID := regexp.MustCompile(`^instance-`) - valid := validInstanceID.MatchString(instanceID) - if !valid { - return nil, goof.WithError("InstanceID not valid", err) - } - instanceID = strings.Replace(instanceID, "instance-", "", 1) - iid := &types.InstanceID{Driver: rackspace.Name} - if err := iid.MarshalMetadata(instanceID); err != nil { - return nil, err - } - return iid, nil -} - -func (d *driver) NextDevice( - ctx types.Context, - opts types.Store) (string, error) { - return "", types.ErrNotImplemented -} - -func (d *driver) LocalDevices( - ctx types.Context, - opts *types.LocalDevicesOpts) (*types.LocalDevices, error) { - // Read from /proc/partitions - localDevices := make(map[string]string) - file := "/proc/partitions" - contentBytes, err := ioutil.ReadFile(file) - if err != nil { - return nil, goof.WithError( - "Error reading /proc/partitions", err) - } - - content := string(contentBytes) - - // Parse device names - var deviceName string - lines := strings.Split(content, "\n") - for _, line := range lines[2:] { - fields := strings.Fields(line) - if len(fields) == 4 { - deviceName = "/dev/" + fields[3] - localDevices[deviceName] = deviceName - } - } - - return &types.LocalDevices{ - Driver: rackspace.Name, - DeviceMap: localDevices, - }, nil - -} diff --git a/drivers/storage/rackspace/rackspace.go b/drivers/storage/rackspace/rackspace.go deleted file mode 100644 index 71b0f023..00000000 --- a/drivers/storage/rackspace/rackspace.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build none - -package rackspace - -import ( - gofigCore "github.com/akutz/gofig" - gofig "github.com/akutz/gofig/types" -) - -// Name is the provider's name. -const Name string = "rackspace" - -func init() { - r := gofigCore.NewRegistration("Rackspace") - r.Key(gofig.String, "", "", "", "rackspace.authURL") - r.Key(gofig.String, "", "", "", "rackspace.userID") - r.Key(gofig.String, "", "", "", "rackspace.userName") - r.Key(gofig.String, "", "", "", "rackspace.password") - r.Key(gofig.String, "", "", "", "rackspace.tenantID") - r.Key(gofig.String, "", "", "", "rackspace.tenantName") - r.Key(gofig.String, "", "", "", "rackspace.domainID") - r.Key(gofig.String, "", "", "", "rackspace.domainName") - gofigCore.Register(r) -} diff --git a/drivers/storage/rackspace/storage/rackspace_storage.go b/drivers/storage/rackspace/storage/rackspace_storage.go deleted file mode 100644 index a896dcd7..00000000 --- a/drivers/storage/rackspace/storage/rackspace_storage.go +++ /dev/null @@ -1,771 +0,0 @@ -// +build none - -package storage - -import ( - "os/exec" - "regexp" - "strings" - "time" - - log "github.com/Sirupsen/logrus" - gofig "github.com/akutz/gofig/types" - "github.com/akutz/goof" - - "github.com/codedellemc/libstorage/api/context" - "github.com/codedellemc/libstorage/api/registry" - "github.com/codedellemc/libstorage/api/types" - apiUtils "github.com/codedellemc/libstorage/api/utils" - "github.com/codedellemc/libstorage/drivers/storage/rackspace" - - "github.com/rackspace/gophercloud" - "github.com/rackspace/gophercloud/openstack" - "github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots" - "github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes" - "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach" -) - -const ( - providerName = "Rackspace" - minSize = 75 //rackspace is 75 -) - -type driver struct { - provider *gophercloud.ProviderClient - client *gophercloud.ServiceClient - clientBlockStorage *gophercloud.ServiceClient - region string - instanceID string - config gofig.Config -} - -func init() { - registry.RegisterStorageDriver(rackspace.Name, newDriver) -} - -func newDriver() types.StorageDriver { - return &driver{} -} - -func (d *driver) Name() string { - return rackspace.Name -} - -func (d *driver) Init(context types.Context, config gofig.Config) error { - d.config = config - - fields := eff(map[string]interface{}{}) - var err error - - if d.instanceID, err = d.getInstanceID(); err != nil { - return err - } - - fields["moduleName"] = context - fields["instanceId"] = d.instanceID - - if d.region, err = d.getInstanceRegion(); err != nil { - return err - } - - fields["region"] = d.region - d.region = strings.ToUpper(d.region) - - authOpts := d.getAuthOptions() - - fields["identityEndpoint"] = d.authURL() - fields["userId"] = d.userID() - fields["userName"] = d.userName() - if d.password() == "" { - fields["password"] = "" - } else { - fields["password"] = "******" - } - fields["tenantId"] = d.tenantID() - fields["tenantName"] = d.tenantName() - fields["domainId"] = d.domainID() - fields["domainName"] = d.domainName() - - if d.provider, err = openstack.AuthenticatedClient(authOpts); err != nil { - return goof.WithFieldsE(fields, - "error getting authenticated client", err) - } - - if d.client, err = openstack.NewComputeV2(d.provider, - gophercloud.EndpointOpts{Region: d.region}); err != nil { - goof.WithFieldsE(fields, "error getting newComputeV2", err) - } - - if d.clientBlockStorage, err = openstack.NewBlockStorageV1(d.provider, - gophercloud.EndpointOpts{Region: d.region}); err != nil { - return goof.WithFieldsE(fields, - "error getting newBlockStorageV1", err) - } - - log.WithFields(fields).Info("storage driver initialized") - return nil - -} - -// // Type returns the type of storage the driver provides. -func (d *driver) Type(ctx types.Context) (types.StorageType, error) { - return types.Block, nil -} - -// // NextDeviceInfo returns the information about the driver's next available -// // device workflow. -func (d *driver) NextDeviceInfo( - ctx types.Context) (*types.NextDeviceInfo, error) { - return nil, nil -} - -// // InstanceInspect returns an instance. -func (d *driver) InstanceInspect( - ctx types.Context, - opts types.Store) (*types.Instance, error) { - - iid := context.MustInstanceID(ctx) - if iid.ID != "" { - return &types.Instance{InstanceID: iid}, nil - } - var rsSubnetID string - if err := iid.UnmarshalMetadata(&rsSubnetID); err != nil { - return nil, err - } - instanceID := &types.InstanceID{ID: rsSubnetID, Driver: d.Name()} - return &types.Instance{InstanceID: instanceID}, nil -} - -// // Volumes returns all volumes or a filtered list of volumes. -func (d *driver) Volumes( - ctx types.Context, - opts *types.VolumesOpts) ([]*types.Volume, error) { - // always return attachments to align against other drivers for now - return d.getVolume(ctx, "", "", opts.Attachments) -} - -// // VolumeInspect inspects a single volume. -func (d *driver) VolumeInspect( - ctx types.Context, - volumeID string, - opts *types.VolumeInspectOpts) (*types.Volume, error) { - if volumeID == "" { - return nil, goof.New("no volumeID specified") - } - - vols, err := d.getVolume(ctx, volumeID, "", opts.Attachments) - if err != nil { - return nil, err - } - - if vols == nil { - return nil, apiUtils.NewNotFoundError(volumeID) - } - return vols[0], nil -} - -// // VolumeCreate creates a new volume. -func (d *driver) VolumeCreate(ctx types.Context, volumeName string, - opts *types.VolumeCreateOpts) (*types.Volume, error) { - - return d.createVolume(ctx, volumeName, "", "", opts) -} - -// // VolumeCreateFromSnapshot creates a new volume from an existing snapshot. -func (d *driver) VolumeCreateFromSnapshot( - ctx types.Context, - snapshotID, volumeName string, - opts *types.VolumeCreateOpts) (*types.Volume, error) { - return d.createVolume(ctx, volumeName, "", snapshotID, opts) - -} - -// // VolumeCopy copies an existing volume. -func (d *driver) VolumeCopy( - ctx types.Context, - volumeID, volumeName string, - opts types.Store) (*types.Volume, error) { - volume, err := d.VolumeInspect(ctx, volumeID, &types.VolumeInspectOpts{}) - if err != nil { - return nil, - goof.New("error getting reference volume for volume copy") - } - - volumeCreateOpts := &types.VolumeCreateOpts{ - Type: &volume.Type, - AvailabilityZone: &volume.AvailabilityZone, - } - - return d.createVolume(ctx, volumeName, volumeID, "", volumeCreateOpts) -} - -// // VolumeSnapshot snapshots a volume. -func (d *driver) VolumeSnapshot( - ctx types.Context, - volumeID, snapshotName string, - opts types.Store) (*types.Snapshot, error) { - - fields := eff(map[string]interface{}{ - "moduleName": ctx, - "snapshotName": snapshotName, - "volumeId": volumeID, - }) - - createOpts := snapshots.CreateOpts{ - Name: snapshotName, - VolumeID: volumeID, - Force: true, - } - - resp, err := snapshots.Create(d.clientBlockStorage, createOpts).Extract() - if err != nil { - return nil, - goof.WithFieldsE(fields, "error creating snapshot", err) - } - - log.Debug("waiting for snapshot creation to complete") - d.waitSnapshotStatus(ctx, resp.ID) - return translateSnapshot(resp), nil -} - -// // VolumeRemove removes a volume. -func (d *driver) VolumeRemove( - ctx types.Context, - volumeID string, - opts *types.VolumeRemoveOpts) error { - fields := eff(map[string]interface{}{ - "volumeId": volumeID, - }) - if volumeID == "" { - return goof.WithFields(fields, "volumeId is required") - } - - attached, err := d.volumeAttached(ctx, volumeID) - if err != nil { - return goof.WithFieldsE(fields, "error retrieving attachment status", err) - } - - if attached { - _, err := d.VolumeDetach(ctx, volumeID, &types.VolumeDetachOpts{}) - if err != nil { - return goof.WithFieldsE(fields, "error detaching before volume removal", err) - } - } - - res := volumes.Delete(d.clientBlockStorage, volumeID) - if res.Err != nil { - return goof.WithFieldsE(fields, "error removing volume", res.Err) - } - - return nil -} - -// // VolumeAttach attaches a volume and provides a token clients can use -// // to validate that device has appeared locally. -func (d *driver) VolumeAttach( - ctx types.Context, - volumeID string, - opts *types.VolumeAttachOpts) (*types.Volume, string, error) { - iid := context.MustInstanceID(ctx) - fields := eff(map[string]interface{}{ - "volumeId": volumeID, - "instanceId": iid.ID, - }) - - if opts.Force { - if _, err := d.VolumeDetach(ctx, volumeID, - &types.VolumeDetachOpts{}); err != nil { - return nil, "", err - } - } - - options := &volumeattach.CreateOpts{ - VolumeID: volumeID, - } - if opts.NextDevice != nil { - options.Device = *opts.NextDevice - } - - volumeAttach, err := volumeattach.Create(d.client, iid.ID, options).Extract() - if err != nil { - return nil, "", goof.WithFieldsE( - fields, "error attaching volume", err) - } - - ctx.WithFields(fields).Debug("waiting for volume to attach") - volume, err := d.waitVolumeAttachStatus(ctx, volumeID, true) - if err != nil { - return nil, "", goof.WithFieldsE( - fields, "error waiting for volume to attach", err) - } - return volume, volumeAttach.Device, nil -} - -// // VolumeDetach detaches a volume. -func (d *driver) VolumeDetach( - ctx types.Context, - volumeID string, - opts *types.VolumeDetachOpts) (*types.Volume, error) { - fields := eff(map[string]interface{}{ - "moduleName": ctx, - "volumeId": volumeID, - }) - - if volumeID == "" { - return nil, goof.WithFields(fields, "volumeId is required for VolumeDetach") - } - vols, err := d.getVolume(ctx, volumeID, "", types.VolAttReqTrue) - if err != nil { - return nil, err - } - - resp := volumeattach.Delete( - d.client, vols[0].Attachments[0].InstanceID.ID, volumeID) - if resp.Err != nil { - return nil, goof.WithFieldsE(fields, "error detaching volume", resp.Err) - } - ctx.WithFields(fields).Debug("waiting for volume to detach") - volume, err := d.waitVolumeAttachStatus(ctx, volumeID, false) - if err == nil { - return volume, nil - } - log.WithFields(fields).Debug("volume detached") - return nil, nil -} - -// // Not a part of storage interface -// Not implemented in Anywhere??? -func (d *driver) VolumeDetachAll( - ctx types.Context, - volumeID string, - opts types.Store) error { - return nil -} - -// // Snapshots returns all volumes or a filtered list of snapshots. -func (d *driver) Snapshots( - ctx types.Context, - opts types.Store) ([]*types.Snapshot, error) { - allPages, err := snapshots.List(d.clientBlockStorage, nil).AllPages() - if err != nil { - return []*types.Snapshot{}, - goof.WithError("error listing volume snapshots", err) - } - allSnapshots, err := snapshots.ExtractSnapshots(allPages) - if err != nil { - return []*types.Snapshot{}, - goof.WithError("error listing volume snapshots", err) - } - - var libstorageSnapshots []*types.Snapshot - for _, snapshot := range allSnapshots { - libstorageSnapshots = append(libstorageSnapshots, translateSnapshot(&snapshot)) - } - - return libstorageSnapshots, nil -} - -// // SnapshotInspect inspects a single snapshot. -func (d *driver) SnapshotInspect( - ctx types.Context, - snapshotID string, - opts types.Store) (*types.Snapshot, error) { - fields := eff(map[string]interface{}{ - "snapshotId": snapshotID, - }) - - snapshot, err := snapshots.Get(d.clientBlockStorage, snapshotID).Extract() - if err != nil { - return nil, - goof.WithFieldsE(fields, "error getting snapshot", err) - } - - return translateSnapshot(snapshot), nil -} - -// // SnapshotCopy copies an existing snapshot. -func (d *driver) SnapshotCopy( - ctx types.Context, - snapshotID, snapshotName, destinationID string, - opts types.Store) (*types.Snapshot, error) { - - // TODO - return nil, types.ErrNotImplemented -} - -// // SnapshotRemove removes a snapshot. -func (d *driver) SnapshotRemove( - ctx types.Context, - snapshotID string, - opts types.Store) error { - resp := snapshots.Delete(d.clientBlockStorage, snapshotID) - if resp.Err != nil { - return goof.WithFieldsE(goof.Fields{ - "snapshotId": snapshotID}, "error removing snapshot", resp.Err) - } - - return nil -} - -/////////////////////////////////////////////////////////////////////// -///// HELPER FUNCTIONS FOR RACKSPACE DRIVER FROM THIS POINT ON //////// -/////////////////////////////////////////////////////////////////////// - -func (d *driver) getAuthOptions() gophercloud.AuthOptions { - return gophercloud.AuthOptions{ - IdentityEndpoint: d.authURL(), - UserID: d.userID(), - Username: d.userName(), - Password: d.password(), - TenantID: d.tenantID(), - TenantName: d.tenantName(), - DomainID: d.domainID(), - DomainName: d.domainName(), - } -} - -func (d *driver) getInstanceID() (string, error) { - cmd := exec.Command("xenstore-read", "name") - cmd.Env = d.config.EnvVars() - cmdOut, err := cmd.Output() - - if err != nil { - return "", - goof.WithError("problem getting instance ID", err) - } - - instanceID := strings.Replace(string(cmdOut), "\n", "", -1) - - validInstanceID := regexp.MustCompile(`^instance-`) - valid := validInstanceID.MatchString(instanceID) - if !valid { - return "", - goof.WithError("InstanceID not valid", err) - } - instanceID = strings.Replace(instanceID, "instance-", "", 1) - return instanceID, nil -} - -func (d *driver) getInstanceRegion() (string, error) { - cmd := exec.Command("xenstore-read", - "vm-data/provider_data/region") - cmd.Env = d.config.EnvVars() - cmdOut, err := cmd.Output() - - if err != nil { - return "", - goof.WithError("problem getting instance region", err) - //return "", - // goof.WithFields(eff(goof.Fields{ - // "moduleName": d.r.Context, - // "cmd.Path": cmd.Path, - // "cmd.Args": cmd.Args, - // "cmd.Out": cmdOut, - // }), "error getting instance region") - } - - region := strings.Replace(string(cmdOut), "\n", "", -1) - return region, nil -} - -func (d *driver) getVolume( - ctx types.Context, - volumeID, volumeName string, - attachments types.VolumeAttachmentsTypes) ([]*types.Volume, error) { - - var volumesRet []volumes.Volume - fields := eff(goof.Fields{ - "moduleName": ctx, - "volumeId": volumeID, - "volumeName": volumeName}) - - if volumeID != "" { - volume, err := volumes.Get(d.clientBlockStorage, volumeID).Extract() - if err != nil { - return nil, - goof.WithFieldsE(fields, "error getting volumes", err) - } - volumesRet = append(volumesRet, *volume) - } else { - listOpts := &volumes.ListOpts{ - //Name: volumeName, - } - - allPages, err := volumes.List(d.clientBlockStorage, listOpts).AllPages() - if err != nil { - return nil, - goof.WithFieldsE(fields, "error listing volumes", err) - } - volumesRet, err = volumes.ExtractVolumes(allPages) - if err != nil { - return nil, - goof.WithFieldsE(fields, "error extracting volumes", err) - } - - var volumesRetFiltered []volumes.Volume - if volumeName != "" { - for _, volumer := range volumesRet { //volumer avoids any namespace confict - if volumer.Name == volumeName { - volumesRetFiltered = append(volumesRetFiltered, volumer) - break - } - } - volumesRet = volumesRetFiltered - } - } - //now cast from []volumes.Volume to []types.Volume - var volumesSD []*types.Volume - for _, volume := range volumesRet { - volumesSD = append(volumesSD, translateVolume(&volume, attachments)) - } - return volumesSD, nil -} - -func createVolumeEnsureSize(size *int64) { - if *size != 0 && *size < minSize { - *size = minSize - } -} - -func (d *driver) createVolume( - ctx types.Context, - volumeName string, - volumeSourceID string, - snapshotID string, - opts *types.VolumeCreateOpts) (*types.Volume, error) { - var ( - volumeType string - IOPS int64 - size int64 - availabilityZone string - ) - if opts.Type != nil { - volumeType = *(opts.Type) - } - if opts.IOPS != nil { - IOPS = *(opts.IOPS) - } - if opts.Size != nil { - size = *(opts.Size) - } - if opts.AvailabilityZone != nil { - availabilityZone = *(opts.AvailabilityZone) - } - - //check some fields... - createVolumeEnsureSize(&size) - vsize := int(size) - - fields := map[string]interface{}{ - "availabilityZone": availabilityZone, - "iops": IOPS, - "provider": d.Name(), - "size": size, - "snapshotId": snapshotID, - "volumeName": volumeName, - "volumeSourceID": volumeSourceID, - "volumeType": volumeType, - } - - options := &volumes.CreateOpts{ - Name: volumeName, - Size: vsize, - SnapshotID: snapshotID, - VolumeType: volumeType, - //AvailabilityZone: availabilityZone, //Not in old Rackspace - //SourceReplica: volumeSourceID, - } - resp, err := volumes.Create(d.clientBlockStorage, options).Extract() - if err != nil { - return nil, - goof.WithFields(fields, "error creating volume") - } - fields["volumeId"] = resp.ID - //for openstack must test before rackspace integration - err = volumes.WaitForStatus(d.clientBlockStorage, resp.ID, "available", 120) - if err != nil { - return nil, - goof.WithFieldsE(fields, - "error waiting for volume creation to complete", err) - } - log.WithFields(fields).Debug("created volume") - return translateVolume(resp, types.VolAttReqTrue), nil -} - -//Reformats from volumes.Volume to types.Volume credit to github.com/MatMaul -func translateVolume( - volume *volumes.Volume, - attachments types.VolumeAttachmentsTypes) *types.Volume { - - var atts []*types.VolumeAttachment - if attachments.Requested() { - for _, att := range volume.Attachments { - lsAtt := &types.VolumeAttachment{ - VolumeID: att["volume_id"].(string), - InstanceID: &types.InstanceID{ - ID: att["server_id"].(string), - Driver: rackspace.Name}, - } - if attachments.Devices() { - lsAtt.DeviceName = att["device"].(string) - } - atts = append(atts, lsAtt) - } - } - - return &types.Volume{ - Name: volume.Name, - ID: volume.ID, - AvailabilityZone: volume.AvailabilityZone, - Status: volume.Status, - Type: volume.VolumeType, - IOPS: 0, - Size: int64(volume.Size), - Attachments: atts, - } -} - -//Reformats from snapshots.Snapshot to types.Snapshot credit to github.com/MatMaul -func translateSnapshot(snapshot *snapshots.Snapshot) *types.Snapshot { - createAtEpoch := int64(0) - createdAt, err := time.Parse(time.RFC3339Nano, snapshot.CreatedAt) - if err == nil { - createAtEpoch = createdAt.Unix() - } - return &types.Snapshot{ - Name: snapshot.Name, - VolumeID: snapshot.VolumeID, - ID: snapshot.ID, - VolumeSize: int64(snapshot.Size), - StartTime: createAtEpoch, - Description: snapshot.Description, - Status: snapshot.Status, - } -} -func (d *driver) volumeAttached(ctx types.Context, - volumeID string) (bool, error) { - fields := eff(map[string]interface{}{ - "moduleName": ctx, - "volumeId": volumeID, - }) - if volumeID == "" { - return true, goof.WithFields(fields, "volumeId is required") - } - volume, err := d.VolumeInspect( - ctx, volumeID, &types.VolumeInspectOpts{ - Attachments: types.VolAttReqTrue}) - if err != nil { - return true, goof.WithFieldsE(fields, "error getting volume when waiting", err) - } - if len(volume.Attachments) > 0 { - return true, nil - } - if len(volume.Attachments) == 0 { - return false, nil - } - return true, goof.WithFields(fields, "check volume attachement status failed is required") -} - -func (d *driver) waitSnapshotStatus( - ctx types.Context, snapshotID string) error { - if snapshotID == "" { - return goof.New("Missing snapshot ID") - } - for { - snapshot, err := d.SnapshotInspect(ctx, snapshotID, nil) - if err != nil { - return goof.WithError( - "Error getting snapshot", err) - } - - if snapshot.Status != "creating" { - break - } - - time.Sleep(30 * time.Second) - } - - return nil -} - -func (d *driver) waitVolumeAttachStatus( - ctx types.Context, - volumeID string, - attachmentNeeded bool) (*types.Volume, error) { - fields := eff(map[string]interface{}{ - "moduleName": ctx, - "volumeId": volumeID, - }) - - if volumeID == "" { - return nil, goof.WithFields(fields, "volumeId is required") - } - - for { - volume, err := d.VolumeInspect( - ctx, volumeID, - &types.VolumeInspectOpts{Attachments: types.VolAttReqTrue}) - if err != nil { - return nil, goof.WithFieldsE(fields, "error getting volume when waiting", err) - } - - if attachmentNeeded { - if len(volume.Attachments) > 0 { - return volume, nil - } - } else { - if len(volume.Attachments) == 0 { - return volume, nil - } - } - time.Sleep(1 * time.Second) - } -} - -//error reporting - -func eff(fields goof.Fields) map[string]interface{} { - errFields := map[string]interface{}{ - "provider": providerName, - } - if fields != nil { - for k, v := range fields { - errFields[k] = v - } - } - return errFields -} - -// Plain Accessors - -func (d *driver) authURL() string { - return d.config.GetString("rackspace.authURL") -} - -func (d *driver) userID() string { - return d.config.GetString("rackspace.userID") -} - -func (d *driver) userName() string { - return d.config.GetString("rackspace.userName") -} - -func (d *driver) password() string { - return d.config.GetString("rackspace.password") -} - -func (d *driver) tenantID() string { - return d.config.GetString("rackspace.tenantID") -} - -func (d *driver) tenantName() string { - return d.config.GetString("rackspace.tenantName") -} - -func (d *driver) domainID() string { - return d.config.GetString("rackspace.domainID") -} - -func (d *driver) domainName() string { - return d.config.GetString("rackspace.domainName") -} diff --git a/drivers/storage/rackspace/tests/coverage.mk b/drivers/storage/rackspace/tests/coverage.mk deleted file mode 100644 index 15c99ca2..00000000 --- a/drivers/storage/rackspace/tests/coverage.mk +++ /dev/null @@ -1,2 +0,0 @@ -RACKSPACE_COVERPKG := $(ROOT_IMPORT_PATH)/drivers/storage/rackspace -TEST_COVERPKG_./drivers/storage/rackspace/tests := $(RACKSPACE_COVERPKG),$(RACKSPACE_COVERPKG)/executor \ No newline at end of file diff --git a/drivers/storage/rackspace/tests/rackspace_test.go b/drivers/storage/rackspace/tests/rackspace_test.go deleted file mode 100644 index a3a4fcc5..00000000 --- a/drivers/storage/rackspace/tests/rackspace_test.go +++ /dev/null @@ -1,529 +0,0 @@ -// +build none - -package rackspace - -import ( - "bytes" - "os" - "strconv" - "strings" - "testing" - - log "github.com/Sirupsen/logrus" - gofig "github.com/akutz/gofig/types" - "github.com/stretchr/testify/assert" - - "github.com/codedellemc/libstorage/api/context" - "github.com/codedellemc/libstorage/api/registry" - "github.com/codedellemc/libstorage/api/server" - apitests "github.com/codedellemc/libstorage/api/tests" - "github.com/codedellemc/libstorage/api/types" - "github.com/codedellemc/libstorage/api/utils" - - // load the driver - rackspace "github.com/codedellemc/libstorage/drivers/storage/rackspace" - rackspacex "github.com/codedellemc/libstorage/drivers/storage/rackspace/executor" - _ "github.com/codedellemc/libstorage/drivers/storage/rackspace/storage" -) - -var ( - configYAML = []byte(` -rackspace: - authURL: https://identity.api.rackspacecloud.com/v2.0 - username: ` + os.Getenv("RACKSPACE_USERNAME") + ` - password: ` + os.Getenv("RACKSPACE_PASSWORD") + ` - availabilityZoneName: ` + os.Getenv("RACKSPACE_AVAILABILITY_ZONE") + ` - regionName: ` + os.Getenv("RACKSPACE_REGION") + ` -`) -) - -var volumeName string -var volumeName2 string - -func skipTests() bool { - travis, _ := strconv.ParseBool(os.Getenv("TRAVIS")) - noTest, _ := strconv.ParseBool(os.Getenv("TEST_SKIP_RACKSPACE")) - return travis || noTest -} - -func init() { - uuid, _ := types.NewUUID() - uuids := strings.Split(uuid.String(), "-") - volumeName = uuids[0] - uuid, _ = types.NewUUID() - uuids = strings.Split(uuid.String(), "-") - volumeName2 = uuids[0] -} - -func TestMain(m *testing.M) { - server.CloseOnAbort() - ec := m.Run() - os.Exit(ec) -} - -func TestInstanceID(t *testing.T) { //PASSES lowercase hidden for testing other stuff - if skipTests() { - t.SkipNow() - } - - sd, err := registry.NewStorageDriver(rackspace.Name) - if err != nil { - t.Fatal(err) - } - - ctx := context.Background() - configR := registry.NewConfig() - if err := configR.ReadConfig(bytes.NewReader(configYAML)); err != nil { - panic(err) - } - if err := sd.Init(ctx, configR); err != nil { - t.Fatal(err) - } - iid, err := rackspacex.InstanceID(configR) - if err != nil { - t.Fatal(err) - } - - ctx = ctx.WithValue(context.InstanceIDKey, iid) - i, err := sd.InstanceInspect(ctx, utils.NewStore()) - if err != nil { - t.Fatal(err) - } - - iid = i.InstanceID - - apitests.Run( - t, rackspace.Name, configYAML, - (&apitests.InstanceIDTest{ - Driver: rackspace.Name, - Expected: iid, - }).Test) -} - -func TestServices(t *testing.T) { //PASSES lowercase hidden for testing other stuff - if skipTests() { - t.SkipNow() - } - - tf := func(config gofig.Config, client types.Client, t *testing.T) { - reply, err := client.API().Services(nil) - assert.NoError(t, err) - assert.Equal(t, len(reply), 1) - - _, ok := reply[rackspace.Name] - assert.True(t, ok) - } - apitests.Run(t, rackspace.Name, configYAML, tf) -} - -func volumeByName( - t *testing.T, client types.Client, volumeName string) *types.Volume { - - log.WithField("volumeName", volumeName).Info("get volume byrackspace.Name") - vols, err := client.API().Volumes(nil, 0) - assert.NoError(t, err) - if err != nil { - t.FailNow() - } - assert.Contains(t, vols, rackspace.Name) - for _, vol := range vols[rackspace.Name] { - if vol.Name == volumeName { - return vol - } - } - t.FailNow() - t.Error("failed volumeByName") - return nil -} - -func TestVolumeCreateRemove(t *testing.T) { //PASSES lowercase hidden for testing other stuff - if skipTests() { - t.SkipNow() - } - tf := func(config gofig.Config, client types.Client, t *testing.T) { - vol := volumeCreate(t, client, volumeName) - volumeRemove(t, client, vol.ID) - } - apitests.Run(t, rackspace.Name, configYAML, tf) -} - -func volumeCreate( - t *testing.T, client types.Client, volumeName string) *types.Volume { - log.WithField("volumeName", volumeName).Info("creating volume") - size := int64(8) - - opts := map[string]interface{}{ - "priority": 2, - "owner": "root@example.com", - } - - volumeCreateRequest := &types.VolumeCreateRequest{ - Name: volumeName, - Size: &size, - Opts: opts, - } - - reply, err := client.API().VolumeCreate(nil, rackspace.Name, volumeCreateRequest) - - assert.NoError(t, err) - if err != nil { - t.FailNow() - t.Error("failed volumeCreate") - } - - apitests.LogAsJSON(reply, t) - assert.Equal(t, volumeName, reply.Name) - assert.Equal(t, int64(75), reply.Size) - return reply -} - -func volumeRemove(t *testing.T, client types.Client, volumeID string) { - log.WithField("volumeID", volumeID).Info("removing volume") - err := client.API().VolumeRemove( - nil, rackspace.Name, volumeID) - assert.NoError(t, err) - if err != nil { - t.Error("failed volumeRemove") - t.FailNow() - } -} - -func TestVolumes(t *testing.T) { //PASSES lowercase hidden for testing other stuff - if skipTests() { - t.SkipNow() - } - - tf := func(config gofig.Config, client types.Client, t *testing.T) { - _ = volumeCreate(t, client, volumeName) - _ = volumeCreate(t, client, volumeName2) - - vol1 := volumeByName(t, client, volumeName) - vol2 := volumeByName(t, client, volumeName2) - - volumeRemove(t, client, vol1.ID) - volumeRemove(t, client, vol2.ID) - } - apitests.Run(t, rackspace.Name, configYAML, tf) -} - -func volumeAttach( - t *testing.T, client types.Client, volumeID string) *types.Volume { - - log.WithField("volumeID", volumeID).Info("attaching volume") - reply, token, err := client.API().VolumeAttach( - nil, rackspace.Name, volumeID, &types.VolumeAttachRequest{}) - - assert.NoError(t, err) - if err != nil { - t.Error("failed volumeAttach") - t.FailNow() - } - apitests.LogAsJSON(reply, t) - assert.NotEqual(t, token, "") - - return reply -} - -func volumeInspect( - t *testing.T, client types.Client, volumeID string) *types.Volume { - - log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, rackspace.Name, volumeID, 0) - assert.NoError(t, err) - - if err != nil { - t.Error("failed volumeInspect") - t.FailNow() - } - apitests.LogAsJSON(reply, t) - return reply -} - -func volumeInspectAttached( - t *testing.T, client types.Client, volumeID string) *types.Volume { - - log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect( - nil, rackspace.Name, volumeID, types.VolAttReqTrue) - assert.NoError(t, err) - - if err != nil { - t.Error("failed volumeInspectAttached") - t.FailNow() - } - apitests.LogAsJSON(reply, t) - assert.Len(t, reply.Attachments, 1) - return reply -} - -func volumeInspectAttachedFail( - t *testing.T, client types.Client, volumeID string) *types.Volume { - - log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect( - nil, rackspace.Name, volumeID, types.VolAttReqTrue) - assert.NoError(t, err) - - if err != nil { - t.Error("failed volumeInspectAttachedFail") - t.FailNow() - } - apitests.LogAsJSON(reply, t) - assert.Len(t, reply.Attachments, 0) - return reply -} - -func volumeInspectDetached( - t *testing.T, client types.Client, volumeID string) *types.Volume { - - log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect( - nil, rackspace.Name, volumeID, types.VolAttReqTrue) - assert.NoError(t, err) - - if err != nil { - t.Error("failed volumeInspectDetached") - t.FailNow() - } - apitests.LogAsJSON(reply, t) - assert.Len(t, reply.Attachments, 0) - apitests.LogAsJSON(reply, t) - return reply -} - -func volumeInspectDetachedFail( - t *testing.T, client types.Client, volumeID string) *types.Volume { - - log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, rackspace.Name, volumeID, 0) - assert.NoError(t, err) - - if err != nil { - t.Error("failed volumeInspectDetachedFail") - t.FailNow() - } - apitests.LogAsJSON(reply, t) - assert.Len(t, reply.Attachments, 1) - apitests.LogAsJSON(reply, t) - return reply -} - -func volumeDetach( - t *testing.T, client types.Client, volumeID string) *types.Volume { - - log.WithField("volumeID", volumeID).Info("detaching volume") - reply, err := client.API().VolumeDetach( - nil, rackspace.Name, volumeID, &types.VolumeDetachRequest{}) - assert.NoError(t, err) - if err != nil { - t.Error("failed volumeDetach") - t.FailNow() - } - apitests.LogAsJSON(reply, t) - assert.Len(t, reply.Attachments, 0) - return reply -} - -func TestVolumeAttach(t *testing.T) { //PASSES lowercase hidden to test other stuff - if skipTests() { - t.SkipNow() - } - var vol *types.Volume - tf := func(config gofig.Config, client types.Client, t *testing.T) { - vol = volumeCreate(t, client, volumeName) - _ = volumeAttach(t, client, vol.ID) - _ = volumeInspectAttached(t, client, vol.ID) - _ = volumeInspectDetachedFail(t, client, vol.ID) - _ = volumeDetach(t, client, vol.ID) - _ = volumeInspectDetached(t, client, vol.ID) - volumeRemove(t, client, vol.ID) - } - apitests.Run(t, rackspace.Name, configYAML, tf) -} - -func testSnapshots(t *testing.T) { //currently fails due to timeout lowercase privated for now - if skipTests() { - t.SkipNow() - } - var vol *types.Volume - var cvol *types.Volume - var snap *types.Snapshot - var csnap *types.Snapshot - tf := func(config gofig.Config, client types.Client, t *testing.T) { - vol = volumeCreate(t, client, volumeName) - snap = volumeSnapshot(t, client, vol.ID, "libstorage test snapshot") - _ = snapshotInspect(t, client, snap.ID) - _ = snapshotByName(t, client, "libstorage test snapshot") - csnap = snapshotCopy(t, client, snap.ID, "listorage snapshot copy", "DestinationID not used") - _ = snapshotInspect(t, client, csnap.ID) - cvol = volumeCreateFromSnapshot(t, client, snap.ID, volumeName2) - _ = volumeInspectDetached(t, client, cvol.ID) - volumeRemove(t, client, cvol.ID) - snapshotRemove(t, client, snap.ID) - snapshotRemove(t, client, csnap.ID) - volumeRemove(t, client, vol.ID) - } - apitests.Run(t, rackspace.Name, configYAML, tf) -} - -func snapshotInspect( - t *testing.T, client types.Client, snapshotID string) *types.Snapshot { - log.WithField("snapshotID", snapshotID).Info("inspecting snapshot") - reply, err := client.API().SnapshotInspect(nil, rackspace.Name, snapshotID) - assert.NoError(t, err) - - if err != nil { - t.Error("failed snapshotInspect") - t.FailNow() - } - apitests.LogAsJSON(reply, t) - return reply -} - -func snapshotByName( - t *testing.T, client types.Client, snapshotName string) *types.Snapshot { - log.WithField("snapshotName", snapshotName).Info("get snapshot by rackspace.Name") - snapshots, err := client.API().Snapshots(nil) - assert.NoError(t, err) - if err != nil { - t.FailNow() - } - assert.Contains(t, snapshots, rackspace.Name) - for _, vol := range snapshots[rackspace.Name] { - if vol.Name == snapshotName { - return vol - } - } - t.FailNow() - t.Error("failed snapshotByName") - return nil -} - -func volumeSnapshot( - t *testing.T, client types.Client, - volumeID, snapshotName string) *types.Snapshot { - log.WithField("snapshotName", snapshotName).Info("creating snapshot") - - /* - opts := map[string]interface{}{ - "priority": 2, - "owner": "root@example.com", - }*/ - - volumeSnapshotRequest := &types.VolumeSnapshotRequest{ - SnapshotName: snapshotName, - // Opts: opts, - } - - reply, err := client.API().VolumeSnapshot(nil, rackspace.Name, - volumeID, volumeSnapshotRequest) - assert.NoError(t, err) - if err != nil { - t.FailNow() - t.Error("failed snapshotCreate") - } - apitests.LogAsJSON(reply, t) - - assert.Equal(t, snapshotName, reply.Name) - assert.Equal(t, volumeID, reply.VolumeID) - return reply -} - -func snapshotCopy( - t *testing.T, client types.Client, - snapshotID, snapshotName, destinationID string) *types.Snapshot { - log.WithField("snapshotName", snapshotName).Info("copying snapshot") - - snapshotCopyRequest := &types.SnapshotCopyRequest{ - SnapshotName: snapshotName, - } - - reply, err := client.API().SnapshotCopy(nil, rackspace.Name, - snapshotID, snapshotCopyRequest) - assert.NoError(t, err) - if err != nil { - t.FailNow() - t.Error("failed snapshotCopy") - } - apitests.LogAsJSON(reply, t) - - assert.Equal(t, snapshotName, reply.Name) - return reply -} - -func snapshotRemove(t *testing.T, client types.Client, snapshotID string) { - log.WithField("snapshotID", snapshotID).Info("removing snapshot") - err := client.API().SnapshotRemove( - nil, rackspace.Name, snapshotID) - assert.NoError(t, err) - - if err != nil { - t.Error("failed snapshotRemove") - t.FailNow() - } -} - -func volumeCreateFromSnapshot( - t *testing.T, client types.Client, - snapshotID, volumeName string) *types.Volume { - fields := map[string]interface{}{ - "snapshotID": snapshotID, - "volumeName": volumeName, - } - log.WithFields(fields).Info("creating volume from snapshot") - size := int64(8) - - opts := map[string]interface{}{ - "priority": 2, - "owner": "root@example.com", - } - - volumeCreateRequest := &types.VolumeCreateRequest{ - Name: volumeName, - Size: &size, - Opts: opts, - } - - reply, err := client.API().VolumeCreateFromSnapshot(nil, - rackspace.Name, snapshotID, volumeCreateRequest) - assert.NoError(t, err) - if err != nil { - t.FailNow() - t.Error("failed volumeCreateFromSnapshot") - } - apitests.LogAsJSON(reply, t) - - assert.Equal(t, volumeName, reply.Name) - assert.Equal(t, size, reply.Size) - assert.Equal(t, opts["priority"], 2) - assert.Equal(t, opts["owner"], "root@example.com") - - return reply -} - -func volumeCopy( - t *testing.T, client types.Client, - volumeID, volumeName string) *types.Volume { - fields := map[string]interface{}{ - "volumeID": volumeID, - "volumeName": volumeName, - } - log.WithFields(fields).Info("copying volume") - - volumeCopyRequest := &types.VolumeCopyRequest{ - VolumeName: volumeName, - } - - reply, err := client.API().VolumeCopy(nil, - rackspace.Name, volumeID, volumeCopyRequest) - assert.NoError(t, err) - if err != nil { - t.FailNow() - t.Error("failed volumeCopy") - } - apitests.LogAsJSON(reply, t) - - assert.Equal(t, volumeName, reply.Name) - - return reply -} diff --git a/glide.lock b/glide.lock index eb8821bc..9ee475a5 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 4a478c781ab4575cf582479cc0409ac554c46e462c840449bde59b2ecd90680f -updated: 2017-04-30T00:14:49.483228771-05:00 +hash: 88231e5eeb06fba6c2357cac76ec831f0f83177aee5838eafd7b76a94d4bb3aa +updated: 2017-05-01T17:04:46.259941056-05:00 imports: - name: cloud.google.com/go version: e4de3dc4493f142c5833f3185e1182025a61f805 @@ -191,21 +191,6 @@ imports: version: d8ed2627bdf02c080bf22230dbb337003b7aba2d subpackages: - difflib -- name: github.com/rackspace/gophercloud - version: 42196eaf5b93739d335921404bb7c5f2205fceb3 - repo: https://github.com/clintonskitson/gophercloud.git - subpackages: - - openstack - - openstack/blockstorage/v1/snapshots - - openstack/blockstorage/v1/volumes - - openstack/compute/v2/extensions/volumeattach - - openstack/identity/v2/tenants - - openstack/identity/v2/tokens - - openstack/identity/v3/tokens - - openstack/utils - - pagination - - testhelper - - testhelper/client - name: github.com/rubiojr/go-vhd version: 96a0db67ea8209453cfa694bdf03de202d6dd8f8 repo: https://github.com/codenrhoden/go-vhd diff --git a/glide.yaml b/glide.yaml index c0789aae..6a0b5a21 100644 --- a/glide.yaml +++ b/glide.yaml @@ -67,11 +67,6 @@ import: version: v1.6.18 repo: https://github.com/aws/aws-sdk-go -### Rackspace - - package: github.com/rackspace/gophercloud - version: 42196eaf5b93739d335921404bb7c5f2205fceb3 - repo: https://github.com/clintonskitson/gophercloud.git - ### GCE - package: golang.org/x/oauth2 version: 314dd2c0bf3ebd592ec0d20847d27e79d0dbe8dd