from .. import mgr
from ..model import nvmeof as model
from ..security import Scope
-from ..services.nvmeof_cli import NvmeofCLICommand
+from ..services.nvmeof_cli import NvmeofCLICommand, convert_to_bytes
from ..services.orchestrator import OrchClient
from ..tools import str_to_bool
from . import APIDoc, APIRouter, BaseController, CreatePermission, \
)
},
)
- @NvmeofCLICommand("nvmeof ns add", model.NamespaceCreation)
@convert_to_model(model.NamespaceCreation)
@handle_nvmeof_error
def create(
)
)
+ @NvmeofCLICommand("nvmeof ns add", model.NamespaceCreation)
+ @convert_to_model(model.NamespaceCreation)
+ @handle_nvmeof_error
+ def create_cli(
+ self,
+ nqn: str,
+ rbd_image_name: str,
+ rbd_pool: str = "rbd",
+ create_image: Optional[bool] = False,
+ size: Optional[str] = None,
+ rbd_image_size: Optional[str] = None,
+ trash_image: Optional[bool] = False,
+ block_size: int = 512,
+ load_balancing_group: Optional[int] = None,
+ force: Optional[bool] = False,
+ no_auto_visible: Optional[bool] = False,
+ disable_auto_resize: Optional[bool] = False,
+ read_only: Optional[bool] = False,
+ gw_group: Optional[str] = None,
+ traddr: Optional[str] = None,
+ ):
+ size_b = rbd_image_size_b = None
+ if size:
+ size_b = convert_to_bytes(size, default_unit='MB')
+ if rbd_image_size:
+ rbd_image_size_b = convert_to_bytes(rbd_image_size, default_unit='MB')
+ return NVMeoFClient(gw_group=gw_group, traddr=traddr).stub.namespace_add(
+ NVMeoFClient.pb2.namespace_add_req(
+ subsystem_nqn=nqn,
+ rbd_image_name=rbd_image_name,
+ rbd_pool_name=rbd_pool,
+ block_size=block_size,
+ create_image=create_image,
+ size=rbd_image_size_b or size_b,
+ trash_image=trash_image,
+ anagrpid=load_balancing_group,
+ force=force,
+ no_auto_visible=no_auto_visible,
+ disable_auto_resize=disable_auto_resize,
+ read_only=read_only
+ )
+ )
+
@ReadPermission
@Endpoint('PUT', '{nsid}/set_qos')
@EndpointDoc(
"traddr": Param(str, "NVMeoF gateway address", True, None),
},
)
- @NvmeofCLICommand("nvmeof ns resize", model=model.RequestStatus)
@convert_to_model(model.RequestStatus)
@handle_nvmeof_error
def resize(
)
)
+ @NvmeofCLICommand("nvmeof ns resize", model=model.RequestStatus)
+ @convert_to_model(model.RequestStatus)
+ @handle_nvmeof_error
+ def resize_cli(
+ self,
+ nqn: str,
+ nsid: str,
+ rbd_image_size: str,
+ gw_group: Optional[str] = None,
+ traddr: Optional[str] = None
+ ):
+ if rbd_image_size:
+ rbd_image_size_b = convert_to_bytes(rbd_image_size, default_unit='MB')
+ mib = 1024 * 1024
+ rbd_image_size_mb = rbd_image_size_b // mib
+
+ return NVMeoFClient(gw_group=gw_group, traddr=traddr).stub.namespace_resize(
+ NVMeoFClient.pb2.namespace_resize_req(
+ subsystem_nqn=nqn, nsid=int(nsid), new_size=rbd_image_size_mb
+ )
+ )
+
@ReadPermission
@Endpoint('PUT', '{nsid}/add_host')
@EndpointDoc(
return -errno.EINVAL, '', str(ex)
+MULTIPLES = ['', "K", "M", "G", "T", "P"]
+UNITS = {
+ f"{prefix}{suffix}": 1024 ** mult
+ for mult, prefix in enumerate(MULTIPLES)
+ for suffix in ['', 'B', 'iB']
+ if not (prefix == '' and suffix == 'iB')
+}
+
+
+def convert_to_bytes(size: Union[int, str], default_unit=None):
+ if isinstance(size, int):
+ number = size
+ size = str(size)
+ else:
+ num_str = ''.join(filter(str.isdigit, size))
+ number = int(num_str)
+ unit_str = ''.join(filter(str.isalpha, size))
+ if not unit_str:
+ if not default_unit:
+ raise ValueError("default unit was not provided")
+ unit_str = default_unit
+
+ if unit_str in UNITS:
+ return number * UNITS[unit_str]
+ raise ValueError(f"Invalid unit: {unit_str}")
+
+
def convert_from_bytes(num_in_bytes):
units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
size = float(num_in_bytes)
from ..model.nvmeof import CliFlags, CliHeader
from ..services.nvmeof_cli import AnnotatedDataTextOutputFormatter, \
- NvmeofCLICommand, convert_from_bytes
+ NvmeofCLICommand, convert_from_bytes, convert_to_bytes
from ..tests import CLICommandTestMixin
assert convert_from_bytes(1048576) == '1MB'
assert convert_from_bytes(123) == '123B'
assert convert_from_bytes(5368709120) == '5GB'
+
+
+class TestConvertToBytes:
+ def test_valid_inputs(self):
+ assert convert_to_bytes('200MB') == 209715200
+ assert convert_to_bytes('1MB') == 1048576
+ assert convert_to_bytes('123B') == 123
+ assert convert_to_bytes('5GB') == 5368709120
+
+ def test_default_unit(self):
+ with pytest.raises(ValueError):
+ assert convert_to_bytes('5') == 5368709120
+ assert convert_to_bytes('5', default_unit='GB') == 5368709120