Skip to content

Commit c1491dc

Browse files
authored
Merge pull request ceph#64516 from Hezko/nvmeof-cli-size-convert3
mgr/dashboard: support human friendly size parameter split commands to separate api and cli functions Reviewed-by: Afreen Misbah <[email protected]> Reviewed-by: Ernesto Puerta <[email protected]>
2 parents 13a09d2 + f93afc4 commit c1491dc

File tree

3 files changed

+107
-2
lines changed

3 files changed

+107
-2
lines changed

src/pybind/mgr/dashboard/controllers/nvmeof.py

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from .. import mgr
1010
from ..model import nvmeof as model
1111
from ..security import Scope
12-
from ..services.nvmeof_cli import NvmeofCLICommand
12+
from ..services.nvmeof_cli import NvmeofCLICommand, convert_to_bytes
1313
from ..services.orchestrator import OrchClient
1414
from ..tools import str_to_bool
1515
from . import APIDoc, APIRouter, BaseController, CreatePermission, \
@@ -470,6 +470,49 @@ def create(
470470
)
471471
)
472472

473+
@NvmeofCLICommand("nvmeof ns add", model.NamespaceCreation)
474+
@convert_to_model(model.NamespaceCreation)
475+
@handle_nvmeof_error
476+
def create_cli(
477+
self,
478+
nqn: str,
479+
rbd_image_name: str,
480+
rbd_pool: str = "rbd",
481+
create_image: Optional[bool] = False,
482+
size: Optional[str] = None,
483+
rbd_image_size: Optional[str] = None,
484+
trash_image: Optional[bool] = False,
485+
block_size: int = 512,
486+
load_balancing_group: Optional[int] = None,
487+
force: Optional[bool] = False,
488+
no_auto_visible: Optional[bool] = False,
489+
disable_auto_resize: Optional[bool] = False,
490+
read_only: Optional[bool] = False,
491+
gw_group: Optional[str] = None,
492+
traddr: Optional[str] = None,
493+
):
494+
size_b = rbd_image_size_b = None
495+
if size:
496+
size_b = convert_to_bytes(size, default_unit='MB')
497+
if rbd_image_size:
498+
rbd_image_size_b = convert_to_bytes(rbd_image_size, default_unit='MB')
499+
return NVMeoFClient(gw_group=gw_group, traddr=traddr).stub.namespace_add(
500+
NVMeoFClient.pb2.namespace_add_req(
501+
subsystem_nqn=nqn,
502+
rbd_image_name=rbd_image_name,
503+
rbd_pool_name=rbd_pool,
504+
block_size=block_size,
505+
create_image=create_image,
506+
size=rbd_image_size_b or size_b,
507+
trash_image=trash_image,
508+
anagrpid=load_balancing_group,
509+
force=force,
510+
no_auto_visible=no_auto_visible,
511+
disable_auto_resize=disable_auto_resize,
512+
read_only=read_only
513+
)
514+
)
515+
473516
@ReadPermission
474517
@Endpoint('PUT', '{nsid}/set_qos')
475518
@NvmeofCLICommand("nvmeof ns set_qos", model=model.RequestStatus)
@@ -583,6 +626,28 @@ def resize(
583626
)
584627
)
585628

629+
@NvmeofCLICommand("nvmeof ns resize", model=model.RequestStatus)
630+
@convert_to_model(model.RequestStatus)
631+
@handle_nvmeof_error
632+
def resize_cli(
633+
self,
634+
nqn: str,
635+
nsid: str,
636+
rbd_image_size: str,
637+
gw_group: Optional[str] = None,
638+
traddr: Optional[str] = None
639+
):
640+
if rbd_image_size:
641+
rbd_image_size_b = convert_to_bytes(rbd_image_size, default_unit='MB')
642+
mib = 1024 * 1024
643+
rbd_image_size_mb = rbd_image_size_b // mib
644+
645+
return NVMeoFClient(gw_group=gw_group, traddr=traddr).stub.namespace_resize(
646+
NVMeoFClient.pb2.namespace_resize_req(
647+
subsystem_nqn=nqn, nsid=int(nsid), new_size=rbd_image_size_mb
648+
)
649+
)
650+
586651
@ReadPermission
587652
@Endpoint('PUT', '{nsid}/add_host')
588653
@NvmeofCLICommand("nvmeof ns add_host", model=model.RequestStatus)

src/pybind/mgr/dashboard/services/nvmeof_cli.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,33 @@ def remove_nvmeof_gateway(_, name: str, daemon_name: str = ''):
5555
return -errno.EINVAL, '', str(ex)
5656

5757

58+
MULTIPLES = ['', "K", "M", "G", "T", "P"]
59+
UNITS = {
60+
f"{prefix}{suffix}": 1024 ** mult
61+
for mult, prefix in enumerate(MULTIPLES)
62+
for suffix in ['', 'B', 'iB']
63+
if not (prefix == '' and suffix == 'iB')
64+
}
65+
66+
67+
def convert_to_bytes(size: Union[int, str], default_unit=None):
68+
if isinstance(size, int):
69+
number = size
70+
size = str(size)
71+
else:
72+
num_str = ''.join(filter(str.isdigit, size))
73+
number = int(num_str)
74+
unit_str = ''.join(filter(str.isalpha, size))
75+
if not unit_str:
76+
if not default_unit:
77+
raise ValueError("default unit was not provided")
78+
unit_str = default_unit
79+
80+
if unit_str in UNITS:
81+
return number * UNITS[unit_str]
82+
raise ValueError(f"Invalid unit: {unit_str}")
83+
84+
5885
def convert_from_bytes(num_in_bytes):
5986
units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
6087
size = float(num_in_bytes)

src/pybind/mgr/dashboard/tests/test_nvmeof_cli.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from ..controllers import EndpointDoc
1111
from ..model.nvmeof import CliFlags, CliHeader
1212
from ..services.nvmeof_cli import AnnotatedDataTextOutputFormatter, \
13-
NvmeofCLICommand, convert_from_bytes
13+
NvmeofCLICommand, convert_from_bytes, convert_to_bytes
1414
from ..tests import CLICommandTestMixin
1515

1616

@@ -458,3 +458,16 @@ def test_valid_inputs(self):
458458
assert convert_from_bytes(1048576) == '1MB'
459459
assert convert_from_bytes(123) == '123B'
460460
assert convert_from_bytes(5368709120) == '5GB'
461+
462+
463+
class TestConvertToBytes:
464+
def test_valid_inputs(self):
465+
assert convert_to_bytes('200MB') == 209715200
466+
assert convert_to_bytes('1MB') == 1048576
467+
assert convert_to_bytes('123B') == 123
468+
assert convert_to_bytes('5GB') == 5368709120
469+
470+
def test_default_unit(self):
471+
with pytest.raises(ValueError):
472+
assert convert_to_bytes('5') == 5368709120
473+
assert convert_to_bytes('5', default_unit='GB') == 5368709120

0 commit comments

Comments
 (0)