// Convert_storage_VolumeAttachment_To_v1beta1_VolumeAttachment is an autogenerated conversion function.
548442
func Convert_storage_VolumeAttachment_To_v1beta1_VolumeAttachment(in *storage.VolumeAttachment, out *v1beta1.VolumeAttachment, s conversion.Scope) error {
	return autoConvert_storage_VolumeAttachment_To_v1beta1_VolumeAttachment(in, out, s)
}
1105613
func VolumeAttachmentInfoFromState(info state.VolumeAttachmentInfo) params.VolumeAttachmentInfo {
	planInfo := &params.VolumeAttachmentPlanInfo{}
	if info.PlanInfo != nil {
		planInfo.DeviceType = info.PlanInfo.DeviceType
		planInfo.DeviceAttributes = info.PlanInfo.DeviceAttributes
	} else {
		planInfo = nil
	}
	return params.VolumeAttachmentInfo{
		info.DeviceName,
		info.DeviceLink,
		info.BusAddress,
		info.ReadOnly,
		planInfo,
	}
}
635007
func (s *oracleVolumeSource) DetachVolumes(ctx context.ProviderCallContext, params []storage.VolumeAttachmentParams) ([]error, error) {
	attachAsMap, err := s.getStorageAttachments()
	if err != nil {
		return nil, errors.Trace(err)
	}
	toDelete := make([]string, len(params))
	ret := make([]error, len(params))
	for i, val := range params {
		found := false
		for _, attach := range attachAsMap[string(val.InstanceId)] {
			if val.VolumeId == attach.Storage_volume_name {
				toDelete[i] = attach.Name
				found = true
			}
		}
		if !found {
			toDelete[i] = ""
			ret[i] = errors.NotFoundf(
				"volume attachment for instance %v and volumeID %v not found",
				val.InstanceId, val.VolumeId)
		}
	}
	for i, val := range toDelete {
		if val == "" {
			continue
		}
		ret[i] = s.api.DeleteStorageAttachment(val)
	}
	return ret, nil
}
1320359
func volumeAttachmentParams(
	ctx *context, ids []params.MachineStorageId,
) ([]storage.VolumeAttachmentParams, error) {
	paramsResults, err := ctx.config.Volumes.VolumeAttachmentParams(ids)
	if err != nil {
		return nil, errors.Annotate(err, "getting volume attachment params")
	}
	attachmentParams := make([]storage.VolumeAttachmentParams, len(ids))
	for i, result := range paramsResults {
		if result.Error != nil {
			return nil, errors.Annotate(result.Error, "getting volume attachment parameters")
		}
		params, err := volumeAttachmentParamsFromParams(result.Result)
		if err != nil {
			return nil, errors.Annotate(err, "getting volume attachment parameters")
		}
		attachmentParams[i] = params
	}
	return attachmentParams, nil
}
135113
func VolumeAttachmentInfosToState(in map[string]params.VolumeAttachmentInfo) (map[names.VolumeTag]state.VolumeAttachmentInfo, error) {
	m := make(map[names.VolumeTag]state.VolumeAttachmentInfo)
	for k, v := range in {
		volumeTag, err := names.ParseVolumeTag(k)
		if err != nil {
			return nil, errors.Trace(err)
		}
		m[volumeTag] = VolumeAttachmentInfoToState(v)
	}
	return m, nil
}
386277
func (d *driver) VolumeAttach(
	ctx types.Context,
	volumeID string,
	opts *types.VolumeAttachOpts) (*types.Volume, string, error) {

	vmName := context.MustInstanceID(ctx).ID

	if opts.NextDevice == nil || *opts.NextDevice == "" {
		return nil, "", errMissingNextDevice
	}

	fields := map[string]interface{}{
		"vmName":     vmName,
		"volumeID":   volumeID,
		"nextDevice": *opts.NextDevice,
	}

	volume, err := d.getVolume(ctx, volumeID,
		types.VolumeAttachmentsRequested)
	if err != nil {
		if _, ok := err.(*types.ErrNotFound); ok {
			return nil, "", err
		}
		return nil, "", goof.WithFieldsE(fields,
			"failed to get volume for attach", err)
	}
	// Check if volume is already attached
	// TODO: maybe add the check that new instance is the same as current
	if len(volume.Attachments) > 0 {
		// Detach already attached volume if forced
		if !opts.Force {
			return nil, "", errVolAlreadyAttached
		}
		for _, att := range volume.Attachments {
			err = d.detachDisk(ctx, &volumeID, &att.InstanceID.ID)
			if err != nil {
				return nil, "", goof.WithError(
					"failed to detach volume first", err)
			}
		}
	}

	vm, err := d.getVM(ctx, vmName)
	if err != nil {
		return nil, "", goof.WithFieldsE(fields,
			"VM could not be obtained", err)
	}

	err = d.attachDisk(ctx, volumeID, volume.Size, vm)
	if err != nil {
		return nil, "", goof.WithFieldsE(fields,
			"failed to attach volume", err)
	}

	volume, err = d.getVolume(ctx, volumeID,
		types.VolumeAttachmentsRequested)
	if err != nil {
		return nil, "", goof.WithFieldsE(fields,
			"failed to get just created/attached volume", err)
	}

	return volume, *opts.NextDevice, nil
}
436780
func (m *Machine) VolumeAttachments() ([]VolumeAttachment, error) {
	sb, err := NewStorageBackend(m.st)
	if err != nil {
		return nil, errors.Trace(err)
	}
	return sb.MachineVolumeAttachments(m.MachineTag())
}
21467
func Convert_v1_VolumeAttachmentSpec_To_storage_VolumeAttachmentSpec(in *v1.VolumeAttachmentSpec, out *storage.VolumeAttachmentSpec, s conversion.Scope) error {
	return autoConvert_v1_VolumeAttachmentSpec_To_storage_VolumeAttachmentSpec(in, out, s)
}
752777
func Convert_storage_VolumeAttachmentList_To_v1beta1_VolumeAttachmentList(in *storage.VolumeAttachmentList, out *v1beta1.VolumeAttachmentList, s conversion.Scope) error {
	return autoConvert_storage_VolumeAttachmentList_To_v1beta1_VolumeAttachmentList(in, out, s)
}
270818
func Convert_v1alpha1_VolumeAttachmentStatus_To_storage_VolumeAttachmentStatus(in *v1alpha1.VolumeAttachmentStatus, out *storage.VolumeAttachmentStatus, s conversion.Scope) error {
	return autoConvert_v1alpha1_VolumeAttachmentStatus_To_storage_VolumeAttachmentStatus(in, out, s)
}
101362
func Convert_storage_VolumeAttachmentList_To_v1_VolumeAttachmentList(in *storage.VolumeAttachmentList, out *v1.VolumeAttachmentList, s conversion.Scope) error {
	return autoConvert_storage_VolumeAttachmentList_To_v1_VolumeAttachmentList(in, out, s)
}
575885
func (s *StorageProvisionerAPIv3) VolumeAttachmentParams(
	args params.MachineStorageIds,
) (params.VolumeAttachmentParamsResults, error) {
	canAccess, err := s.getAttachmentAuthFunc()
	if err != nil {
		return params.VolumeAttachmentParamsResults{}, common.ServerError(common.ErrPerm)
	}
	results := params.VolumeAttachmentParamsResults{
		Results: make([]params.VolumeAttachmentParamsResult, len(args.Ids)),
	}
	one := func(arg params.MachineStorageId) (params.VolumeAttachmentParams, error) {
		volumeAttachment, err := s.oneVolumeAttachment(arg, canAccess)
		if err != nil {
			return params.VolumeAttachmentParams{}, err
		}
		// Volumes can be attached to units (caas models) or machines.
		// We only care about instance id for machine attachments.
		var instanceId instance.Id
		if machineTag, ok := volumeAttachment.Host().(names.MachineTag); ok {
			instanceId, err = s.st.MachineInstanceId(machineTag)
			if errors.IsNotProvisioned(err) {
				// The worker must watch for machine provisioning events.
				instanceId = ""
			} else if err != nil {
				return params.VolumeAttachmentParams{}, err
			}
		}
		volume, err := s.sb.Volume(volumeAttachment.Volume())
		if err != nil {
			return params.VolumeAttachmentParams{}, err
		}
		var volumeId string
		var pool string
		if volumeParams, ok := volume.Params(); ok {
			pool = volumeParams.Pool
		} else {
			volumeInfo, err := volume.Info()
			if err != nil {
				return params.VolumeAttachmentParams{}, err
			}
			volumeId = volumeInfo.VolumeId
			pool = volumeInfo.Pool
		}
		providerType, _, err := storagecommon.StoragePoolConfig(pool, s.poolManager, s.registry)
		if err != nil {
			return params.VolumeAttachmentParams{}, errors.Trace(err)
		}
		var readOnly bool
		if volumeAttachmentParams, ok := volumeAttachment.Params(); ok {
			readOnly = volumeAttachmentParams.ReadOnly
		} else {
			// Attachment parameters may be requested even if the
			// attachment exists; i.e. for reattachment.
			volumeAttachmentInfo, err := volumeAttachment.Info()
			if err != nil {
				return params.VolumeAttachmentParams{}, errors.Trace(err)
			}
			readOnly = volumeAttachmentInfo.ReadOnly
		}
		return params.VolumeAttachmentParams{
			VolumeTag:  volumeAttachment.Volume().String(),
			MachineTag: volumeAttachment.Host().String(),
			VolumeId:   volumeId,
			InstanceId: string(instanceId),
			Provider:   string(providerType),
			ReadOnly:   readOnly,
		}, nil
	}
	for i, arg := range args.Ids {
		var result params.VolumeAttachmentParamsResult
		volumeAttachment, err := one(arg)
		if err != nil {
			result.Error = common.ServerError(err)
		} else {
			result.Result = volumeAttachment
		}
		results.Results[i] = result
	}
	return results, nil
}
518843
func Convert_v1_VolumeDevice_To_core_VolumeDevice(in *v1.VolumeDevice, out *core.VolumeDevice, s conversion.Scope) error {
	return autoConvert_v1_VolumeDevice_To_core_VolumeDevice(in, out, s)
}
346637
func Convert_storage_VolumeAttachmentSpec_To_v1beta1_VolumeAttachmentSpec(in *storage.VolumeAttachmentSpec, out *v1beta1.VolumeAttachmentSpec, s conversion.Scope) error {
	return autoConvert_storage_VolumeAttachmentSpec_To_v1beta1_VolumeAttachmentSpec(in, out, s)
}
1333508
func (sb *storageBackend) VolumeAttachment(host names.Tag, volume names.VolumeTag) (VolumeAttachment, error) {
	coll, cleanup := sb.mb.db().GetCollection(volumeAttachmentsC)
	defer cleanup()

	var att volumeAttachment
	err := coll.FindId(volumeAttachmentId(host.Id(), volume.Id())).One(&att.doc)
	if err == mgo.ErrNotFound {
		return nil, errors.NotFoundf("volume %q on %q", volume.Id(), names.ReadableString(host))
	} else if err != nil {
		return nil, errors.Annotatef(err, "getting volume %q on %q", volume.Id(), names.ReadableString(host))
	}
	return &att, nil
}
194527
func ParseVolumeAttachmentTypes(v interface{}) VolumeAttachmentsTypes {
	switch tv := v.(type) {
	case VolumeAttachmentsTypes:
		return tv
	case int:
		return VolumeAttachmentsTypes(tv)
	case uint:
		return VolumeAttachmentsTypes(tv)
	case int8:
		return VolumeAttachmentsTypes(tv)
	case uint8:
		return VolumeAttachmentsTypes(tv)
	case int16:
		return VolumeAttachmentsTypes(tv)
	case uint16:
		return VolumeAttachmentsTypes(tv)
	case int32:
		return VolumeAttachmentsTypes(tv)
	case uint32:
		return VolumeAttachmentsTypes(tv)
	case int64:
		return VolumeAttachmentsTypes(tv)
	case uint64:
		return VolumeAttachmentsTypes(tv)
	case string:
		if i, err := strconv.ParseInt(tv, 10, 64); err == nil {
			return ParseVolumeAttachmentTypes(i)
		}
		if b, err := strconv.ParseBool(tv); err == nil {
			return ParseVolumeAttachmentTypes(b)
		}
	case bool:
		if tv {
			return VolumeAttachmentsTrue
		}
		return VolumeAttachmentsRequested
	}
	return VolAttNone
}
264520
func Convert_v1alpha1_VolumeAttachment_To_storage_VolumeAttachment(in *v1alpha1.VolumeAttachment, out *storage.VolumeAttachment, s conversion.Scope) error {
	return autoConvert_v1alpha1_VolumeAttachment_To_storage_VolumeAttachment(in, out, s)
}