Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions simplyblock_core/controllers/lvol_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -1755,6 +1755,8 @@ def connect_lvol(uuid, ctrl_loss_tmo=constants.LVOL_NVME_CONNECT_CTRL_LOSS_TMO,
lvol = db_controller.get_lvol_by_id(uuid)
if lvol.status == LVol.STATUS_DELETED:
raise KeyError(f"LVol {uuid} is deleted")
if lvol.status == LVol.STATUS_IN_DELETION:
raise KeyError(f"LVol {uuid} is being deleted")
except KeyError:
logger.exception("Failed to get lvol by id: %s", uuid)
return False, "Failed to find volume"
Expand Down
21 changes: 13 additions & 8 deletions simplyblock_core/controllers/snapshot_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from simplyblock_core.models.job_schedule import JobSchedule
from simplyblock_core.models.pool import Pool
from simplyblock_core.models.snapshot import SnapShot
from simplyblock_core.models.lvol_model import LVol
from simplyblock_core.models.lvol_model import LVol, LVolInDeletionError
from simplyblock_core.models.storage_node import StorageNode


Expand Down Expand Up @@ -613,15 +613,20 @@ def clone(snapshot_id, clone_name, new_size=0, pvc_name=None, pvc_namespace=None
logger.error(msg)
return False, msg

for lvol in db_controller.get_lvols():
if lvol.pool_uuid != pool.get_id() or lvol.lvol_name != clone_name:
continue
if lvol.cloned_from_snap == snapshot_id and lvol.status != LVol.STATUS_IN_DELETION:
logger.info(f"Clone already exists, reusing lvol: {lvol.get_id()}")
return lvol.get_id(), False
msg=f"LVol name must be unique: {clone_name}"
try:
existing = db_controller.get_lvol_by_pool_and_name(pool.get_id(), clone_name)
if existing.cloned_from_snap == snapshot_id:
logger.info(f"Clone already exists, reusing lvol: {existing.get_id()}")
return existing.get_id(), False
msg = f"LVol name must be unique: {clone_name}"
logger.error(msg)
return False, msg
except LVolInDeletionError:
msg = f"Clone {clone_name} is being deleted, retry later"
logger.error(msg)
return False, msg
except KeyError:
pass

size = snap.size
if 0 < pool.lvol_max_size < size:
Expand Down
14 changes: 12 additions & 2 deletions simplyblock_core/db_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from simplyblock_core.models.cluster import Cluster
from simplyblock_core.models.events import EventObj
from simplyblock_core.models.job_schedule import JobSchedule
from simplyblock_core.models.lvol_model import LVol
from simplyblock_core.models.lvol_model import LVol, LVolInDeletionError
from simplyblock_core.models.mgmt_node import MgmtNode
from simplyblock_core.models.nvme_device import NVMeDevice, JMDevice
from simplyblock_core.models.pool import Pool
Expand Down Expand Up @@ -124,7 +124,7 @@ def get_pool_by_name(self, name) -> Pool:

def get_lvols(self, cluster_id=None) -> List[LVol]:
lvols = self.get_all_lvols()
lvols = [lvol for lvol in lvols if lvol.status != LVol.STATUS_DELETED]
lvols = [lvol for lvol in lvols if lvol.status not in (LVol.STATUS_DELETED, LVol.STATUS_IN_DELETION)]
if not cluster_id:
return lvols

Expand Down Expand Up @@ -196,6 +196,16 @@ def get_lvol_by_name(self, lvol_name) -> LVol:
return lvol
raise KeyError(f'LVol {lvol_name} not found')

def get_lvol_by_pool_and_name(self, pool_uuid: str, lvol_name: str) -> LVol:
for lvol in self.get_all_lvols():
if lvol.pool_uuid == pool_uuid and lvol.lvol_name == lvol_name:
if lvol.status == LVol.STATUS_DELETED:
continue
if lvol.status == LVol.STATUS_IN_DELETION:
raise LVolInDeletionError(f"LVol {lvol_name} is being deleted")
return lvol
raise KeyError(f"LVol {lvol_name} not found in pool {pool_uuid}")

def get_mgmt_node_by_id(self, id) -> MgmtNode:
ret = MgmtNode().read_from_db(self.kv_store, id)
if not ret:
Expand Down
4 changes: 4 additions & 0 deletions simplyblock_core/models/lvol_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
from simplyblock_core.models.nvme_device import NVMeDevice


class LVolInDeletionError(Exception):
pass


class LVol(BaseModel):

STATUS_IN_CREATION = 'in_creation'
Expand Down
12 changes: 8 additions & 4 deletions simplyblock_web/api/v1/lvol.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from simplyblock_web import utils

from simplyblock_core import db_controller, utils as core_utils
from simplyblock_core.models.lvol_model import LVolInDeletionError

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -128,10 +129,13 @@ def add_lvol():
if not pool:
return utils.get_response(None, f"Pool not found: {pool_id_or_name}", 400)

for lvol in db.get_lvols(): # pass
if lvol.pool_uuid == pool.get_id():
if lvol.lvol_name == name:
return utils.get_response(lvol.get_id())
try:
existing = db.get_lvol_by_pool_and_name(pool.get_id(), name)
return utils.get_response(existing.get_id())
except LVolInDeletionError:
return utils.get_response(None, f"Volume {name} is being deleted, retry later", 409)
except KeyError:
pass

rw_iops = utils.get_int_value_or_default(cl_data, "max_rw_iops", 0)
rw_mbytes = utils.get_int_value_or_default(cl_data, "max_rw_mbytes", 0)
Expand Down
6 changes: 4 additions & 2 deletions simplyblock_web/api/v2/volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from simplyblock_core.db_controller import DBController
from simplyblock_core import utils as core_utils
from simplyblock_core.controllers import lvol_controller, snapshot_controller
from simplyblock_core.models.lvol_model import LVol
from simplyblock_core.models.lvol_model import LVol, LVolInDeletionError

from .cluster import Cluster
from .pool import StoragePool
Expand Down Expand Up @@ -66,8 +66,10 @@ def add(
) -> Response:
data = parameters.root
try:
db.get_lvol_by_name(data.name)
db.get_lvol_by_pool_and_name(pool.get_id(), data.name)
raise HTTPException(409, f'Volume {data.name} exists')
except LVolInDeletionError:
raise HTTPException(409, f'Volume {data.name} is being deleted, retry later')
except KeyError:
pass

Expand Down
Loading