// ParseVolumeAttachmentTypes parses a value into a VolumeAttachmentsTypes
// value.
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
}
1051620
func Convert_storage_VolumeAttachmentSpec_To_v1alpha1_VolumeAttachmentSpec(in *storage.VolumeAttachmentSpec, out *v1alpha1.VolumeAttachmentSpec, s conversion.Scope) error {
	return autoConvert_storage_VolumeAttachmentSpec_To_v1alpha1_VolumeAttachmentSpec(in, out, s)
}
975370
func setMachineVolumeAttachmentInfo(sb *storageBackend, machineId string, attachments map[names.VolumeTag]VolumeAttachmentInfo) (err error) {
	defer errors.DeferredAnnotatef(&err, "cannot set volume attachment info for machine %s", machineId)
	machineTag := names.NewMachineTag(machineId)
	for volumeTag, info := range attachments {
		if err := sb.setVolumeAttachmentInfo(machineTag, volumeTag, info); err != nil {
			return errors.Annotatef(err, "setting attachment info for volume %s", volumeTag.Id())
		}
	}
	return nil
}
615407
func Convert_v1alpha1_VolumeAttachmentSpec_To_storage_VolumeAttachmentSpec(in *v1alpha1.VolumeAttachmentSpec, out *storage.VolumeAttachmentSpec, s conversion.Scope) error {
	return autoConvert_v1alpha1_VolumeAttachmentSpec_To_storage_VolumeAttachmentSpec(in, out, s)
}
1067799
func (v *azureVolumeSource) DetachVolumes(ctx context.ProviderCallContext, attachParams []storage.VolumeAttachmentParams) ([]error, error) {
	results := make([]error, len(attachParams))
	instanceIds := make([]instance.Id, len(attachParams))
	for i, p := range attachParams {
		instanceIds[i] = p.InstanceId
	}
	if len(instanceIds) == 0 {
		return results, nil
	}
	virtualMachines, err := v.virtualMachines(ctx, instanceIds)
	if err != nil {
		return nil, errors.Annotate(err, "getting virtual machines")
	}

	// Update VirtualMachine objects in-memory,
	// and then perform the updates all at once.
	//
	// An detachment does not require an update
	// if the disk isn't attached, so we keep a
	// record of which VMs need updating.
	changed := make(map[instance.Id]bool, len(virtualMachines))
	for i, p := range attachParams {
		vm, ok := virtualMachines[p.InstanceId]
		if !ok {
			continue
		}
		if vm.err != nil {
			results[i] = vm.err
			continue
		}
		if v.detachVolume(vm.vm, p) {
			changed[p.InstanceId] = true
		}
	}
	for _, instanceId := range instanceIds {
		if !changed[instanceId] {
			delete(virtualMachines, instanceId)
		}
	}

	updateResults, err := v.updateVirtualMachines(ctx, virtualMachines, instanceIds)
	if err != nil {
		return nil, errors.Annotate(err, "updating virtual machines")
	}
	for i, err := range updateResults {
		if results[i] != nil || err == nil {
			continue
		}
		results[i] = err
	}
	return results, nil
}
1226483
func (s *StorediSCSIVolume) SetVolumeAttachmentStatus(v string) *StorediSCSIVolume {
	s.VolumeAttachmentStatus = &v
	return s
}
272678
func (v *version) VolumeAttachments() VolumeAttachmentInformer {
	return &volumeAttachmentInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
}
1119410
func (d *driver) VolumeAttach(
	ctx types.Context,
	volumeID string,
	opts *types.VolumeAttachOpts) (*types.Volume, string, error) {
	// Initialize for logging
	fields := map[string]interface{}{
		"provider": d.Name(),
		"volumeID": volumeID,
	}
	// review volume with attachments to any host
	ec2vols, err := d.getVolume(ctx, volumeID, "")
	if err != nil {
		return nil, "", goof.WithFieldsE(fields, "error getting volume", err)
	}
	volumes, convErr := d.toTypesVolume(
		ctx, ec2vols, types.VolAttReqTrue)
	if convErr != nil {
		return nil, "", goof.WithError(
			"error converting to types.Volume", convErr)
	}

	// Check if there a volume to attach
	if len(volumes) == 0 {
		return nil, "", goof.New("no volume found")
	}

	// Check if volume is already attached
	if len(volumes[0].Attachments) > 0 {
		// Detach already attached volume if forced
		if !opts.Force {
			return nil, "", errVolAlreadyAttached
		}
		_, err := d.VolumeDetach(
			ctx,
			volumeID,
			&types.VolumeDetachOpts{
				Force: opts.Force,
				Opts:  opts.Opts,
			})
		if err != nil {
			return nil, "", goof.WithError("error detaching volume", err)
		}
	}

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

	// tagName: e.g. "vol1"
	tagName := volumes[0].Name
	if tagName == "" {
		return nil, "", goof.WithFields(fields, "error empty Name tag")
	}
	// get fcvol constituent disks by Name tag
	ec2vols, err = d.getVolume(ctx, "", tagName)
	if err != nil {
		return nil, "", goof.WithError("error getting FittedCloud volumes", err)
	}

	// Make sure all volumes are FittedCloudCreated
	allOK := true
	for _, volume := range ec2vols {
		if d.fittedcloudCreated(volume.Tags) == "" {
			allOK = false
			break
		}
	}
	if !allOK {
		return nil, "", goof.WithFields(fields, "not a FittedCloudCreated volume")
	}

	// Attach constituent disks
	nextDevice := *opts.NextDevice
	for _, volume := range ec2vols {
		if nextDevice == "" {
			return nil, "", errMissingNextDevice
		}
		// Attach volume via helper function which uses EC2 API call
		err = d.attachVolume(ctx, *volume.VolumeId, volumes[0].Name, nextDevice)
		if err != nil {
			return nil, "", goof.WithFieldsE(
				log.Fields{
					"provider": d.Name(),
					"volumeID": volume.VolumeId},
				"error attaching volume",
				err,
			)
		}
		// Wait for volume's status to update
		err = d.waitVolumeComplete(ctx, *volume.VolumeId, waitVolumeAttach)
		if err != nil {
			return nil, "", goof.WithError("error waiting for volume attach", err)
		}
		nextDevice, _ = fcUtils.NextDevice(ctx, apiUtils.NewStore())
	}

	// Check if successful attach
	attachedVol, err := d.VolumeInspect(
		ctx, volumeID, &types.VolumeInspectOpts{
			Attachments: types.VolAttReqTrue,
			Opts:        opts.Opts,
		})
	if err != nil {
		return nil, "", goof.WithError("error getting volume", err)
	}

	// Token is the attachment's device name, which will be matched
	// to the executor's device ID
	return attachedVol, *opts.NextDevice, nil
}
987082
func (s *cinderVolumeSource) AttachVolumes(ctx context.ProviderCallContext, args []storage.VolumeAttachmentParams) ([]storage.AttachVolumesResult, error) {
	results := make([]storage.AttachVolumesResult, len(args))
	for i, arg := range args {
		attachment, err := s.attachVolume(arg)
		if err != nil {
			results[i].Error = errors.Trace(err)
			if denial := common.MaybeHandleCredentialError(IsAuthorisationFailure, err, ctx); denial {
				// We do not want to continue here as we'll 100% fail if we got unauthorised error.
				break
			}
			continue
		}
		results[i].VolumeAttachment = attachment
	}
	return results, nil
}
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)
}
898931
func Convert_v1beta1_VolumeAttachmentStatus_To_storage_VolumeAttachmentStatus(in *v1beta1.VolumeAttachmentStatus, out *storage.VolumeAttachmentStatus, s conversion.Scope) error {
	return autoConvert_v1beta1_VolumeAttachmentStatus_To_storage_VolumeAttachmentStatus(in, out, s)
}
599839
func validateVolumeAttachmentStatus(status *storage.VolumeAttachmentStatus, fldPath *field.Path) field.ErrorList {
	allErrs := field.ErrorList{}
	allErrs = append(allErrs, validateAttachmentMetadata(status.AttachmentMetadata, fldPath.Child("attachmentMetadata"))...)
	allErrs = append(allErrs, validateVolumeError(status.AttachError, fldPath.Child("attachError"))...)
	allErrs = append(allErrs, validateVolumeError(status.DetachError, fldPath.Child("detachError"))...)
	return allErrs
}
1043676
func (s *VolumeInfo) SetVolumeAttachmentStatus(v string) *VolumeInfo {
	s.VolumeAttachmentStatus = &v
	return s
}
1002287
func Convert_storage_VolumeAttachment_To_v1alpha1_VolumeAttachment(in *storage.VolumeAttachment, out *v1alpha1.VolumeAttachment, s conversion.Scope) error {
	return autoConvert_storage_VolumeAttachment_To_v1alpha1_VolumeAttachment(in, out, s)
}
686950
func (sb *storageBackend) WatchMachineVolumeAttachments(m names.MachineTag) StringsWatcher {
	return sb.watchHostStorageAttachments(m, volumeAttachmentsC)
}
67126
func (s *StorageProvisionerAPIv3) SetVolumeAttachmentInfo(
	args params.VolumeAttachments,
) (params.ErrorResults, error) {
	canAccess, err := s.getAttachmentAuthFunc()
	if err != nil {
		return params.ErrorResults{}, err
	}
	results := params.ErrorResults{
		Results: make([]params.ErrorResult, len(args.VolumeAttachments)),
	}
	one := func(arg params.VolumeAttachment) error {
		machineTag, volumeTag, volumeAttachmentInfo, err := storagecommon.VolumeAttachmentToState(arg)
		if err != nil {
			return errors.Trace(err)
		}
		if !canAccess(machineTag, volumeTag) {
			return common.ErrPerm
		}
		err = s.sb.SetVolumeAttachmentInfo(machineTag, volumeTag, volumeAttachmentInfo)
		if errors.IsNotFound(err) {
			return common.ErrPerm
		}
		return errors.Trace(err)
	}
	for i, arg := range args.VolumeAttachments {
		err := one(arg)
		results.Results[i].Error = common.ServerError(err)
	}
	return results, nil
}
375721
func filesystemAttachmentParams(
	ctx *context, ids []params.MachineStorageId,
) ([]storage.FilesystemAttachmentParams, error) {
	paramsResults, err := ctx.config.Filesystems.FilesystemAttachmentParams(ids)
	if err != nil {
		return nil, errors.Annotate(err, "getting filesystem attachment params")
	}
	attachmentParams := make([]storage.FilesystemAttachmentParams, len(ids))
	for i, result := range paramsResults {
		if result.Error != nil {
			return nil, errors.Annotate(result.Error, "getting filesystem attachment parameters")
		}
		params, err := filesystemAttachmentParamsFromParams(result.Result)
		if err != nil {
			return nil, errors.Annotate(err, "getting filesystem attachment parameters")
		}
		attachmentParams[i] = params
	}
	return attachmentParams, nil
}