lxd/storage_pools.go
func storagePoolDelete(d *Daemon, r *http.Request) Response {
	poolName := mux.Vars(r)["name"]

	poolID, err := d.cluster.StoragePoolGetID(poolName)
	if err != nil {
		return NotFound(err)
	}

	// If this is not an internal cluster request, check if the storage
	// pool has any volumes associated with it, if so error out.
	if !isClusterNotification(r) {
		response := storagePoolDeleteCheckPreconditions(d.cluster, poolName, poolID)
		if response != nil {
			return response
		}
	}

	// Check if the pool is pending, if so we just need to delete it from
	// the database.
	_, pool, err := d.cluster.StoragePoolGet(poolName)
	if err != nil {
		return SmartError(err)
	}
	if pool.Status == "Pending" {
		_, err := d.cluster.StoragePoolDelete(poolName)
		if err != nil {
			return SmartError(err)
		}
		return EmptySyncResponse
	}

	s, err := storagePoolInit(d.State(), poolName)
	if err != nil {
		return InternalError(err)
	}

	// If this is a notification for a ceph pool deletion, we don't want to
	// actually delete the pool, since that will be done by the node that
	// notified us. We just need to delete the local mountpoint.
	if s, ok := s.(*storageCeph); ok && isClusterNotification(r) {
		// Delete the mountpoint for the storage pool.
		poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
		if shared.PathExists(poolMntPoint) {
			err := os.RemoveAll(poolMntPoint)
			if err != nil {
				return SmartError(err)
			}
		}
		return EmptySyncResponse
	}

	volumeNames, err := d.cluster.StoragePoolVolumesGetNames(poolID)
	if err != nil {
		return InternalError(err)
	}

	for _, volume := range volumeNames {
		_, imgInfo, err := d.cluster.ImageGet("default", volume, false, false)
		if err != nil {
			return InternalError(err)
		}

		err = doDeleteImageFromPool(d.State(), imgInfo.Fingerprint, poolName)
		if err != nil {
			return InternalError(err)
		}
	}

	err = s.StoragePoolDelete()
	if err != nil {
		return InternalError(err)
	}

	// If this is a cluster notification, we're done, any database work
	// will be done by the node that is originally serving the request.
	if isClusterNotification(r) {
		return EmptySyncResponse
	}

	// If we are clustered, also notify all other nodes, if any.
	clustered, err := cluster.Enabled(d.db)
	if err != nil {
		return SmartError(err)
	}
	if clustered {
		notifier, err := cluster.NewNotifier(d.State(), d.endpoints.NetworkCert(), cluster.NotifyAll)
		if err != nil {
			return SmartError(err)
		}
		err = notifier(func(client lxd.ContainerServer) error {
			_, _, err := client.GetServer()
			if err != nil {
				return err
			}
			return client.DeleteStoragePool(poolName)
		})
		if err != nil {
			return SmartError(err)
		}
	}

	err = dbStoragePoolDeleteAndUpdateCache(d.cluster, poolName)
	if err != nil {
		return SmartError(err)
	}

	return EmptySyncResponse
}
func storagePoolDelete(d *Daemon, r *http.Request) Response {
	poolName := mux.Vars(r)["name"]

	poolID, err := d.cluster.StoragePoolGetID(poolName)
	if err != nil {
		return NotFound(err)
	}

	// If this is not an internal cluster request, check if the storage
	// pool has any volumes associated with it, if so error out.
	if !isClusterNotification(r) {
		response := storagePoolDeleteCheckPreconditions(d.cluster, poolName, poolID)
		if response != nil {
			return response
		}
	}

	// Check if the pool is pending, if so we just need to delete it from
	// the database.
	_, pool, err := d.cluster.StoragePoolGet(poolName)
	if err != nil {
		return SmartError(err)
	}
	if pool.Status == "Pending" {
		_, err := d.cluster.StoragePoolDelete(poolName)
		if err != nil {
			return SmartError(err)
		}
		return EmptySyncResponse
	}

	s, err := storagePoolInit(d.State(), poolName)
	if err != nil {
		return InternalError(err)
	}

	// If this is a notification for a ceph pool deletion, we don't want to
	// actually delete the pool, since that will be done by the node that
	// notified us. We just need to delete the local mountpoint.
	if s, ok := s.(*storageCeph); ok && isClusterNotification(r) {
		// Delete the mountpoint for the storage pool.
		poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
		if shared.PathExists(poolMntPoint) {
			err := os.RemoveAll(poolMntPoint)
			if err != nil {
				return SmartError(err)
			}
		}
		return EmptySyncResponse
	}

	volumeNames, err := d.cluster.StoragePoolVolumesGetNames(poolID)
	if err != nil {
		return InternalError(err)
	}

	for _, volume := range volumeNames {
		_, imgInfo, err := d.cluster.ImageGet("default", volume, false, false)
		if err != nil {
			return InternalError(err)
		}

		err = doDeleteImageFromPool(d.State(), imgInfo.Fingerprint, poolName)
		if err != nil {
			return InternalError(err)
		}
	}

	err = s.StoragePoolDelete()
	if err != nil {
		return InternalError(err)
	}

	// If this is a cluster notification, we're done, any database work
	// will be done by the node that is originally serving the request.
	if isClusterNotification(r) {
		return EmptySyncResponse
	}

	// If we are clustered, also notify all other nodes, if any.
	clustered, err := cluster.Enabled(d.db)
	if err != nil {
		return SmartError(err)
	}
	if clustered {
		notifier, err := cluster.NewNotifier(d.State(), d.endpoints.NetworkCert(), cluster.NotifyAll)
		if err != nil {
			return SmartError(err)
		}
		err = notifier(func(client lxd.ContainerServer) error {
			_, _, err := client.GetServer()
			if err != nil {
				return err
			}
			return client.DeleteStoragePool(poolName)
		})
		if err != nil {
			return SmartError(err)
		}
	}

	err = dbStoragePoolDeleteAndUpdateCache(d.cluster, poolName)
	if err != nil {
		return SmartError(err)
	}

	return EmptySyncResponse
}
// /1.0/storage-pools/{name}
// Delete storage pool.