func (d *driver) VolumeAttach( ctx types.Context, volumeID string, opts *types.VolumeAttachOpts) (*types.Volume, string, error) { var modVol *types.Volume for _, vol := range d.volumes { if vol.ID == volumeID { modVol = vol break } } modVol.Attachments = []*types.VolumeAttachment{ &types.VolumeAttachment{ DeviceName: *opts.NextDevice, MountPoint: "", InstanceID: context.MustInstanceID(ctx), Status: "attached", VolumeID: modVol.ID, }, } return modVol, "1234", nil }
func (d *driver) createVolume(ctx types.Context, volumeName string, vol *types.Volume) (*siotypes.VolumeResp, error) { volumeName = shrink(volumeName) fields := eff(map[string]interface{}{ // "volumeID": volumeID, "volumeName": volumeName, "volumeType": vol.Type, "IOPS": vol.IOPS, "size": vol.Size, "availabilityZone": vol.AvailabilityZone, }) volumeParam := &siotypes.VolumeParam{ Name: volumeName, VolumeSizeInKb: strconv.Itoa(int(vol.Size) * 1024 * 1024), VolumeType: d.thinOrThick(), } if vol.Type == "" { vol.Type = d.storagePool.StoragePool.Name fields["volumeType"] = vol.Type } volumeResp, err := d.client.CreateVolume(volumeParam, vol.Type) if err != nil { return nil, goof.WithFieldsE(fields, "error creating volume", err) } return volumeResp, nil }
func (d *driver) VolumeDetach( ctx types.Context, volumeID string, opts *types.VolumeDetachOpts) (*types.Volume, error) { var modVol *types.Volume for _, vol := range d.volumes { if vol.ID == volumeID { modVol = vol break } } modVol.Attachments = nil return modVol, nil }
func handleVolAttachments( ctx types.Context, lf log.Fields, iid *types.InstanceID, vol *types.Volume, attachments types.VolumeAttachmentsTypes) bool { if attachments == 0 { vol.Attachments = nil return true } if lf == nil { lf = log.Fields{} } f := func(s types.VolumeAttachmentStates) bool { lf["attachmentState"] = s // if the volume has no attachments and the mask indicates that // only attached volumes should be returned then omit this volume if s == types.VolumeAvailable && attachments.Attached() && !attachments.Unattached() { ctx.WithFields(lf).Debug("omitting unattached volume") return false } // if the volume has attachments and the mask indicates that // only unattached volumes should be returned then omit this volume if (s == types.VolumeAttached || s == types.VolumeUnavailable) && !attachments.Attached() && attachments.Unattached() { ctx.WithFields(lf).Debug("omitting attached volume") return false } ctx.WithFields(lf).Debug("including volume") return true } // if the attachment state has already been set by the driver then // use it to determine whether the volume should be omitted if vol.AttachmentState > 0 { ctx.WithFields(lf).Debug( "deferring to driver-specified attachment state") return f(vol.AttachmentState) } ctx.WithFields(lf).Debug("manually calculating attachment state") // if only the requesting instance's attachments are requested then // filter the volume's attachments list if attachments.Mine() { atts := []*types.VolumeAttachment{} for _, a := range vol.Attachments { alf := log.Fields{ "attDeviceName": a.DeviceName, "attDountPoint": a.MountPoint, "attVolumeID": a.VolumeID, } if strings.EqualFold(iid.ID, a.InstanceID.ID) { atts = append(atts, a) ctx.WithFields(lf).WithFields(alf).Debug( "including volume attachment") } else { ctx.WithFields(lf).WithFields(alf).Debug( "omitting volume attachment") } } vol.Attachments = atts ctx.WithFields(lf).Debug("included volume attached to instance") } // determine a volume's attachment state if len(vol.Attachments) == 0 { vol.AttachmentState = types.VolumeAvailable } else { vol.AttachmentState = types.VolumeUnavailable if iid != nil { for _, a := range vol.Attachments { if a.InstanceID != nil && strings.EqualFold(iid.ID, a.InstanceID.ID) { vol.AttachmentState = types.VolumeAttached break } } } } // use the ascertained attachment state to determine whether or not the // volume should be omitted return f(vol.AttachmentState) }