// RemoveVolumeAttachmentPlan removes the volume attachment plan from state.
978762
func (sb *storageBackend) RemoveVolumeAttachmentPlan(hostTag names.Tag, volume names.VolumeTag) (err error) {
	defer errors.DeferredAnnotatef(&err, "removing attachment plan of volume %s from machine %s", volume.Id(), hostTag.Id())
	buildTxn := func(attempt int) ([]txn.Op, error) {
		plans, err := sb.machineVolumeAttachmentPlans(hostTag, volume)
		if errors.IsNotFound(err) {
			return nil, jujutxn.ErrNoOperations
		}
		if err != nil {
			return nil, errors.Trace(err)
		}
		// We should only have one plan for a volume
		if plans != nil && len(plans) > 0 {
			if plans[0].Life() != Dying {
				return nil, jujutxn.ErrNoOperations
			}
		} else {
			return nil, jujutxn.ErrNoOperations
		}
		return removeVolumeAttachmentPlanOps(hostTag, volume), nil
	}
	return sb.mb.db().Run(buildTxn)
}
217457
func removeVolumeParams(ctx *context, tags []names.VolumeTag) ([]params.RemoveVolumeParams, error) {
	paramsResults, err := ctx.config.Volumes.RemoveVolumeParams(tags)
	if err != nil {
		return nil, errors.Annotate(err, "getting volume params")
	}
	allParams := make([]params.RemoveVolumeParams, len(tags))
	for i, result := range paramsResults {
		if result.Error != nil {
			return nil, errors.Annotate(result.Error, "getting volume removal parameters")
		}
		allParams[i] = result.Result
	}
	return allParams, nil
}
199281
func (sb *storageBackend) RemoveFilesystemAttachment(host names.Tag, filesystem names.FilesystemTag) (err error) {
	defer errors.DeferredAnnotatef(&err, "removing attachment of filesystem %s from %s", filesystem.Id(), names.ReadableString(host))
	buildTxn := func(attempt int) ([]txn.Op, error) {
		attachment, err := sb.FilesystemAttachment(host, filesystem)
		if errors.IsNotFound(err) && attempt > 0 {
			// We only ignore IsNotFound on attempts after the
			// first, since we expect the filesystem attachment to
			// be there initially.
			return nil, jujutxn.ErrNoOperations
		}
		if err != nil {
			return nil, errors.Trace(err)
		}
		if attachment.Life() != Dying {
			return nil, errors.New("filesystem attachment is not dying")
		}
		f, err := getFilesystemByTag(sb.mb, filesystem)
		if err != nil {
			return nil, errors.Trace(err)
		}
		ops, err := removeFilesystemAttachmentOps(sb, host, f)
		if err != nil {
			return nil, errors.Trace(err)
		}
		volumeAttachment, err := sb.filesystemVolumeAttachment(host, filesystem)
		if err != nil {
			if errors.Cause(err) != ErrNoBackingVolume && !errors.IsNotFound(err) {
				return nil, errors.Trace(err)
			}
		} else {
			// The filesystem is backed by a volume. Since the
			// filesystem has been detached, we should now
			// detach the volume as well if it is detachable.
			// If the volume is not detachable, we'll just
			// destroy it along with the filesystem.
			volume := volumeAttachment.Volume()
			detachableVolume, err := isDetachableVolumeTag(sb.mb.db(), volume)
			if err != nil {
				return nil, errors.Trace(err)
			}
			if detachableVolume {
				plans, err := sb.machineVolumeAttachmentPlans(host, volume)
				if err != nil {
					return nil, errors.Trace(err)
				}
				// NOTE(gsamfira): if we're upgrading, we might not have plans set up,
				// so we check if volume plans were created, and if not, just skip to
				// detaching the actual disk
				var volOps []txn.Op
				if plans == nil || len(plans) == 0 {
					volOps = detachVolumeOps(host, volume)
				} else {
					volOps = detachStorageAttachmentOps(host, volume)
				}
				ops = append(ops, volOps...)
			}
		}
		return ops, nil
	}
	return sb.mb.db().Run(buildTxn)
}
933122
func (ec2i *FakeEC2Impl) DeleteVolume(request *ec2.DeleteVolumeInput) (resp *ec2.DeleteVolumeOutput, err error) {
	panic("Not implemented")
}
405246
func processAliveVolumeAttachments(
	ctx *context,
	ids []params.MachineStorageId,
	volumeAttachmentResults []params.VolumeAttachmentResult,
) error {
	// Filter out the already-attached.
	pending := make([]params.MachineStorageId, 0, len(ids))
	for i, result := range volumeAttachmentResults {
		if result.Error == nil {
			// Volume attachment is already provisioned: if we
			// didn't (re)attach in this session, then we must
			// do so now.
			action := "nothing to do"
			if _, ok := ctx.volumeAttachments[ids[i]]; !ok {
				// Not yet (re)attached in this session.
				pending = append(pending, ids[i])
				action = "will reattach"
			}
			logger.Debugf(
				"%s is already attached to %s, %s",
				ids[i].AttachmentTag, ids[i].MachineTag, action,
			)
			removePendingVolumeAttachment(ctx, ids[i])
			continue
		}
		if !params.IsCodeNotProvisioned(result.Error) {
			return errors.Annotatef(
				result.Error, "getting information for attachment %v", ids[i],
			)
		}
		// The volume has not yet been provisioned, so record its tag
		// to enquire about parameters below.
		pending = append(pending, ids[i])
	}
	if len(pending) == 0 {
		return nil
	}
	params, err := volumeAttachmentParams(ctx, pending)
	if err != nil {
		return errors.Trace(err)
	}
	for i, params := range params {
		if params.Machine.Kind() != names.MachineTagKind {
			logger.Debugf("not queuing volume attachment for non-machine %v", params.Machine)
			continue
		}
		if volume, ok := ctx.volumes[params.Volume]; ok {
			params.VolumeId = volume.VolumeId
		}
		updatePendingVolumeAttachment(ctx, pending[i], params)
	}
	return nil
}
1368603
func removePendingVolume(ctx *context, tag names.VolumeTag) {
	delete(ctx.incompleteVolumeParams, tag)
	ctx.schedule.Remove(tag)
}
817606
func (c *Client) DeleteVolume(
	ctx context.Context, name string) error {
	_, err := apiv1.DeleteIsiVolume(ctx, c.API, name)
	return err
}
1089176
func (d *driver) VolumeRemove(
	ctx types.Context,
	volumeID string,
	opts *types.VolumeRemoveOpts) error {

	zone, err := d.validZone(ctx)
	if err != nil {
		return err
	}

	if zone == nil || *zone == "" {
		return goof.New("Zone is required for VolumeRemove")
	}

	// TODO: check if disk is still attached first
	asyncOp, err := mustSession(ctx).Disks.Delete(
		*d.projectID, *zone, volumeID).Do()
	if err != nil {
		return goof.WithError("Failed to initiate disk deletion", err)
	}

	err = d.waitUntilOperationIsFinished(
		ctx, zone, asyncOp)
	if err != nil {
		return err
	}

	return nil
}
687718
func (s *VolumeSource) DetachVolumes(ctx context.ProviderCallContext, params []storage.VolumeAttachmentParams) ([]error, error) {
	s.MethodCall(s, "DetachVolumes", ctx, params)
	if s.DetachVolumesFunc != nil {
		return s.DetachVolumesFunc(ctx, params)
	}
	return nil, errors.NotImplementedf("DetachVolumes")
}
145858
func DeleteVolumeProfile(key string) error {
	collections.volumeProfileMutex.Lock()
	obj := collections.volumeProfiles[key]
	collections.volumeProfileMutex.Unlock()
	if obj == nil {
		log.Errorf("volumeProfile %s not found", key)
		return errors.New("volumeProfile not found")
	}

	// Check if we handle this object
	if objCallbackHandler.VolumeProfileCb == nil {
		log.Errorf("No callback registered for volumeProfile object")
		return errors.New("Invalid object type")
	}

	// Perform callback
	err := objCallbackHandler.VolumeProfileCb.VolumeProfileDelete(obj)
	if err != nil {
		log.Errorf("VolumeProfileDelete retruned error for: %+v. Err: %v", obj, err)
		return err
	}

	// delete it from modeldb
	collections.volumeProfileMutex.Lock()
	err = obj.Delete()
	collections.volumeProfileMutex.Unlock()
	if err != nil {
		log.Errorf("Error deleting volumeProfile %s. Err: %v", obj.Key, err)
	}

	// delete it from cache
	collections.volumeProfileMutex.Lock()
	delete(collections.volumeProfiles, key)
	collections.volumeProfileMutex.Unlock()

	return nil
}
782839
func (v VolumePathHandler) RemoveMapPath(mapPath string) error {
	if len(mapPath) == 0 {
		return fmt.Errorf("Failed to remove map path. mapPath is empty")
	}
	klog.V(5).Infof("RemoveMapPath: mapPath %s", mapPath)
	err := os.RemoveAll(mapPath)
	if err != nil && !os.IsNotExist(err) {
		return err
	}
	return nil
}
31673
func (d *driver) VolumeRemove(
	ctx types.Context,
	volumeID string,
	opts *types.VolumeRemoveOpts) error {

	//TODO check if volume is attached? if so fail

	_, err := mustSession(ctx).blobClient.DeleteBlobIfExists(
		d.container, volumeID, nil)
	if err != nil {
		fields := map[string]interface{}{
			"volumeID": volumeID,
		}
		return goof.WithFieldsE(fields, "error removing volume", err)
	}
	return nil
}
698227
func (d *driver) VolumeAttach(
	ctx types.Context,
	volumeID string,
	opts *types.VolumeAttachOpts) (*types.Volume, string, error) {

	zone, err := d.validZone(ctx)
	if err != nil {
		return nil, "", err
	}

	if zone == nil || *zone == "" {
		return nil, "", goof.New("Zone is required for VolumeAttach")
	}

	instanceName := context.MustInstanceID(ctx).ID
	gceInst, err := d.getInstance(ctx, zone, &instanceName)
	if err != nil {
		return nil, "", err
	}
	if gceInst == nil {
		return nil, "", goof.New("Instance to attach to not found")
	}

	// Check if volume is already attached somewhere, if so, force detach?
	gceDisk, err := d.getDisk(ctx, zone, &volumeID)
	if err != nil {
		return nil, "", err
	}
	if gceDisk == nil {
		return nil, "", apiUtils.NewNotFoundError(volumeID)
	}

	if len(gceDisk.Users) > 0 {
		if !opts.Force {
			return nil, "", goof.New(
				"Volume already attached to different host")
		}
		ctx.Info("Automatically detaching volume from other instance")
		err = d.detachVolume(ctx, gceDisk)
		if err != nil {
			return nil, "", goof.WithError(
				"Error detaching volume during force attach",
				err)
		}
	}

	err = d.attachVolume(ctx, &instanceName, zone, &volumeID)
	if err != nil {
		return nil, "", err
	}

	vol, err := d.VolumeInspect(
		ctx, volumeID, &types.VolumeInspectOpts{
			Attachments: types.VolAttReq,
			Opts:        opts.Opts,
		},
	)
	if err != nil {
		return nil, "", goof.WithError("Error getting volume", err)
	}

	return vol, volumeID, nil
}
720491
func (util *portworxVolumeUtil) DetachVolume(u *portworxVolumeUnmounter) error {
	driver, err := util.getLocalPortworxDriver(u.plugin.host)
	if err != nil || driver == nil {
		klog.Errorf("Failed to get portworx driver. Err: %v", err)
		return err
	}

	err = driver.Detach(u.volName, false /*doNotForceDetach*/)
	if err != nil {
		klog.Errorf("Error detaching Portworx Volume (%v): %v", u.volName, err)
		return err
	}
	return nil
}
106560
func validateVolumeAttachmentSpec(
	spec *storage.VolumeAttachmentSpec, fldPath *field.Path) field.ErrorList {
	allErrs := field.ErrorList{}
	allErrs = append(allErrs, validateAttacher(spec.Attacher, fldPath.Child("attacher"))...)
	allErrs = append(allErrs, validateVolumeAttachmentSource(&spec.Source, fldPath.Child("source"))...)
	allErrs = append(allErrs, validateNodeName(spec.NodeName, fldPath.Child("nodeName"))...)
	return allErrs
}
605976
func detachVolumes(ctx *context, ops map[params.MachineStorageId]*detachVolumeOp) error {
	volumeAttachmentParams := make([]storage.VolumeAttachmentParams, 0, len(ops))
	for _, op := range ops {
		volumeAttachmentParams = append(volumeAttachmentParams, op.args)
	}
	paramsBySource, volumeSources, err := volumeAttachmentParamsBySource(
		ctx.config.StorageDir, volumeAttachmentParams, ctx.config.Registry,
	)
	if err != nil {
		return errors.Trace(err)
	}
	var reschedule []scheduleOp
	var statuses []params.EntityStatusArgs
	var remove []params.MachineStorageId
	for sourceName, volumeAttachmentParams := range paramsBySource {
		logger.Debugf("detaching volumes: %+v", volumeAttachmentParams)
		volumeSource := volumeSources[sourceName]
		if volumeSource == nil {
			// The storage provider does not support dynamic
			// storage, there's nothing for the provisioner
			// to do here.
			continue
		}
		errs, err := volumeSource.DetachVolumes(ctx.config.CloudCallContext, volumeAttachmentParams)
		if err != nil {
			return errors.Annotatef(err, "detaching volumes from source %q", sourceName)
		}
		for i, err := range errs {
			p := volumeAttachmentParams[i]
			statuses = append(statuses, params.EntityStatusArgs{
				Tag: p.Volume.String(),
				// TODO(axw) when we support multiple
				// attachment, we'll have to check if
				// there are any other attachments
				// before saying the status "detached".
				Status: status.Detached.String(),
			})
			id := params.MachineStorageId{
				MachineTag:    p.Machine.String(),
				AttachmentTag: p.Volume.String(),
			}
			entityStatus := &statuses[len(statuses)-1]
			if err != nil {
				reschedule = append(reschedule, ops[id])
				entityStatus.Status = status.Detaching.String()
				entityStatus.Info = err.Error()
				logger.Debugf(
					"failed to detach %s from %s: %v",
					names.ReadableString(p.Volume),
					names.ReadableString(p.Machine),
					err,
				)
				continue
			}
			remove = append(remove, id)
		}
	}
	scheduleOperations(ctx, reschedule...)
	setStatus(ctx, statuses)
	if err := removeAttachments(ctx, remove); err != nil {
		return errors.Annotate(err, "removing attachments from state")
	}
	for _, id := range remove {
		delete(ctx.volumeAttachments, id)
	}
	return nil
}
935458
func (c *Client) DeleteVolume(p *DeleteVolumeParameter) (*Result, error) {
	obj, err := c.Request("deleteVolume", convertParamToMap(p))
	if err != nil {
		return nil, err
	}
	return obj.(*Result), err
}