def _delete_image(self, target_pool, image_name, snapshot_name=None, context=None): """ Delete RBD image and snapshot. :param image_name: Image's name :param snapshot_name: Image snapshot's name :raises: NotFound if image does not exist; InUseByStore if image is in use or snapshot unprotect failed """ with self.get_connection(conffile=self.conf_file, rados_id=self.user) as conn: with conn.open_ioctx(target_pool) as ioctx: try: # First remove snapshot. if snapshot_name is not None: with rbd.Image(ioctx, image_name) as image: try: self._unprotect_snapshot(image, snapshot_name) image.remove_snap(snapshot_name) except rbd.ImageNotFound as exc: msg = (_("Snap Operating Exception " "%(snap_exc)s " "Snapshot does not exist.") % { 'snap_exc': exc }) LOG.debug(msg) except rbd.ImageBusy as exc: log_msg = (_LE("Snap Operating Exception " "%(snap_exc)s " "Snapshot is in use.") % { 'snap_exc': exc }) LOG.error(log_msg) raise exceptions.InUseByStore() # Then delete image. rbd.RBD().remove(ioctx, image_name) except rbd.ImageHasSnapshots: log_msg = (_LE("Remove image %(img_name)s failed. " "It has snapshot(s) left.") % { 'img_name': image_name }) LOG.error(log_msg) raise exceptions.HasSnapshot() except rbd.ImageBusy: log_msg = (_LE("Remove image %(img_name)s failed. " "It is in use.") % { 'img_name': image_name }) LOG.error(log_msg) raise exceptions.InUseByStore() except rbd.ImageNotFound: msg = _("RBD image %s does not exist") % image_name raise exceptions.NotFound(message=msg)
def _delete_image(self, target_pool, image_name, snapshot_name=None, context=None): """ Delete RBD image and snapshot. :param image_name Image's name :param snapshot_name Image snapshot's name :raises NotFound if image does not exist; InUseByStore if image is in use or snapshot unprotect failed """ with self.get_connection(conffile=self.conf_file, rados_id=self.user) as conn: with conn.open_ioctx(target_pool) as ioctx: try: # First remove snapshot. if snapshot_name is not None: with rbd.Image(ioctx, image_name) as image: try: image.unprotect_snap(snapshot_name) except rbd.ImageBusy: log_msg = _("snapshot %(image)s@%(snap)s " "could not be unprotected because " "it is in use") LOG.debug(log_msg % { 'image': image_name, 'snap': snapshot_name }) raise exceptions.InUseByStore() image.remove_snap(snapshot_name) # Then delete image. rbd.RBD().remove(ioctx, image_name) except rbd.ImageNotFound: msg = _("RBD image %s does not exist") % image_name raise exceptions.NotFound(message=msg) except rbd.ImageBusy: log_msg = _("image %s could not be removed " "because it is in use") LOG.debug(log_msg % image_name) raise exceptions.InUseByStore()
def _del_rbd_image(dest_url, image_id): """Delete image from RBD""" rbd_loc = _parse_rbd_location(dest_url) if not rbd_loc: reason = "Not a Ceph RBD image" raise exception.InvalidRbdUrl(image_id=image_id, url=dest_url) else: _prefix, pool, image_name, snapshot = (str(x) for x in rbd_loc) ceph_cfg_file = CONF.glance_store.rbd_store_ceph_conf LOG.info( _LI("Deleting %(dest_url)s of %(image_id)s from RBD") % { 'dest_url': dest_url, 'image_id': image_id }) with rados.Rados(conffile=ceph_cfg_file) as cluster: with cluster.open_ioctx(str(pool)) as ioctx: try: # First remove snapshot. if snapshot is not None: with rbd.Image(ioctx, image_name) as image: try: if image.is_protected_snap(snapshot): image.unprotect_snap(snapshot) # image.unlock('glance') image.remove_snap(snapshot) except rbd.ImageBusy: reason = _("snapshot %(image)s@%(snap)s could " "not be unprotected because it is " "in use") % { 'image': image_name, 'snap': snapshot } LOG.debug(reason) raise store_exceptions.InUseByStore() except rbd.ImageNotFound: # Not an issue if it does not have snapshots pass # Then delete image. # Note: A caching may be in progress on other controller # when glance-api is started because sometimes glance-api # process is not cleanly stopped and a 'rbd import' process # keeps our image in use for some time - we just have to # patiently wait here retry_cnt = _WAIT_FOR_IMAGE_RELEASE while True: try: rbd.RBD().remove(ioctx, image_name) break except rbd.ImageBusy: if retry_cnt <= 0: raise else: retry_cnt -= 5 reason = _("image %(image)s could not be " "removed because it is in use, " "waiting %(time)s seconds for its " "release") % { 'image': image_name, 'time': retry_cnt } LOG.debug(reason) time.sleep(5) except rbd.ImageNotFound: # If it does not exist then that's good! pass except rbd.ImageBusy: reason = _("image %s could not be removed " "because it is in use") LOG.debug(reason % image_name) raise store_exceptions.InUseByStore()