//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, } }
// getVolume searches and returns a volume matching criteria func (d *driver) getVolume( ctx types.Context, volumeID string, volumeName string, attachments types.VolumeAttachmentsTypes) ([]*types.Volume, error) { if err := d.refreshSession(ctx); err != nil { return nil, err } volumes, err := d.vbox.GetMedium(volumeID, volumeName) if err != nil { return nil, err } if len(volumes) == 0 { return nil, nil } var mapDN map[string]string if attachments.Devices() { volumeMapping, err := d.getVolumeMapping(ctx) if err != nil { return nil, err } mapDN = make(map[string]string) for _, vm := range volumeMapping { mapDN[vm.ID] = vm.Name } } var volumesSD []*types.Volume for _, v := range volumes { volumeSD := &types.Volume{ Name: v.Name, ID: v.ID, Size: int64(v.LogicalSize / 1024 / 1024 / 1024), Status: v.Location, Type: string(v.DeviceType), } if attachments.Requested() { var attachmentsSD []*types.VolumeAttachment for _, mid := range v.MachineIDs { attachmentSD := &types.VolumeAttachment{ VolumeID: v.ID, InstanceID: &types.InstanceID{ ID: mid, Driver: vbox.Name, }, } if attachments.Devices() && mapDN != nil { dn, _ := mapDN[v.ID] attachmentSD.DeviceName = dn } attachmentsSD = append(attachmentsSD, attachmentSD) } volumeSD.Attachments = attachmentsSD } volumesSD = append(volumesSD, volumeSD) } return volumesSD, nil }
func (d *driver) getVolumeAttachments( ctx types.Context, volumeID string, attachments types.VolumeAttachmentsTypes) ( []*types.VolumeAttachment, error) { if !attachments.Requested() { return nil, nil } if volumeID == "" { return nil, goof.New("missing volume ID") } resp, err := mustSession(ctx).DescribeMountTargets( &awsefs.DescribeMountTargetsInput{ FileSystemId: aws.String(volumeID), }) if err != nil { return nil, err } var ( ld *types.LocalDevices ldOK bool ) if attachments.Devices() { // Get local devices map from context if ld, ldOK = context.LocalDevices(ctx); !ldOK { return nil, errGetLocDevs } } var atts []*types.VolumeAttachment for _, mountTarget := range resp.MountTargets { var ( dev string status string ) if ldOK { // TODO(kasisnu): Check lifecycle state and build the path better dev = *mountTarget.IpAddress + ":" + "/" if _, ok := ld.DeviceMap[dev]; ok { status = "Exported and Mounted" } else { status = "Exported and Unmounted" } } else { status = "Exported" } attachmentSD := &types.VolumeAttachment{ VolumeID: *mountTarget.FileSystemId, InstanceID: &types.InstanceID{ ID: *mountTarget.SubnetId, Driver: d.Name(), }, DeviceName: dev, Status: status, } atts = append(atts, attachmentSD) } return atts, nil }
// Converts EC2 API volumes to libStorage types.Volume func (d *driver) toTypesVolume( ctx types.Context, ec2vols []*awsec2.Volume, attachments types.VolumeAttachmentsTypes) ([]*types.Volume, error) { var ( ld *types.LocalDevices ldOK bool ) if attachments.Devices() { // Get local devices map from context if ld, ldOK = context.LocalDevices(ctx); !ldOK { return nil, errGetLocDevs } } var volumesSD []*types.Volume for _, volume := range ec2vols { var attachmentsSD []*types.VolumeAttachment if attachments.Requested() { // Leave attachment's device name blank if attachments is false for _, attachment := range volume.Attachments { deviceName := "" if attachments.Devices() { // Compensate for kernel volume mapping i.e. change // "/dev/sda" to "/dev/xvda" deviceName = strings.Replace( *attachment.Device, "sd", ebsUtils.NextDeviceInfo.Prefix, 1) // Keep device name if it is found in local devices if _, ok := ld.DeviceMap[deviceName]; !ok { deviceName = "" } } attachmentSD := &types.VolumeAttachment{ VolumeID: *attachment.VolumeId, InstanceID: &types.InstanceID{ ID: *attachment.InstanceId, Driver: d.Name(), }, DeviceName: deviceName, Status: *attachment.State, } attachmentsSD = append(attachmentsSD, attachmentSD) } } name := d.getName(volume.Tags) volumeSD := &types.Volume{ Name: name, ID: *volume.VolumeId, AvailabilityZone: *volume.AvailabilityZone, Encrypted: *volume.Encrypted, Status: *volume.State, Type: *volume.VolumeType, Size: *volume.Size, Attachments: attachmentsSD, } // Some volume types have no IOPS, so we get nil in volume.Iops if volume.Iops != nil { volumeSD.IOPS = *volume.Iops } volumesSD = append(volumesSD, volumeSD) } return volumesSD, nil }