Example #1
0
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)
}