From 059e7abce1ffa64387ea2a4ab1b79e1de2f1e55c Mon Sep 17 00:00:00 2001 From: mulhern Date: Wed, 27 Nov 2024 11:39:27 -0500 Subject: [PATCH] Add options for specifying integrity metadata pre-allocations Signed-off-by: mulhern --- src/stratis_cli/_actions/_pool.py | 12 ++++++-- src/stratis_cli/_parser/_pool.py | 37 +++++++++++++++++++++-- src/stratis_cli/_parser/_range.py | 17 ++++++++++- tests/whitebox/integration/test_parser.py | 14 +++++++++ 4 files changed, 75 insertions(+), 5 deletions(-) diff --git a/src/stratis_cli/_actions/_pool.py b/src/stratis_cli/_actions/_pool.py index a492002d4..6a22c3a0d 100644 --- a/src/stratis_cli/_actions/_pool.py +++ b/src/stratis_cli/_actions/_pool.py @@ -199,8 +199,16 @@ def create_pool(namespace): # pylint: disable=too-many-locals if clevis_info is None else (True, (clevis_info.pin, json.dumps(clevis_info.config))) ), - "journal_size": (False, 0), - "tag_size": (False, 0), + "journal_size": ( + (False, 0) + if namespace.journal_size is None + else (True, namespace.journal_size.magnitude.numerator) + ), + "tag_size": ( + (False, 0) + if namespace.tag_size is None + else (True, namespace.tag_size.magnitude.numerator) + ), }, ) diff --git a/src/stratis_cli/_parser/_pool.py b/src/stratis_cli/_parser/_pool.py index 27a829783..93c017e10 100644 --- a/src/stratis_cli/_parser/_pool.py +++ b/src/stratis_cli/_parser/_pool.py @@ -25,7 +25,7 @@ from .._error_codes import PoolErrorCode from ._bind import BIND_SUBCMDS, REBIND_SUBCMDS from ._debug import POOL_DEBUG_SUBCMDS -from ._range import RejectAction +from ._range import RejectAction, parse_bytes_range, parse_range class ClevisEncryptionOptions: # pylint: disable=too-few-public-methods @@ -163,7 +163,40 @@ def _ensure_nat(arg): ) ], }, - ) + ), + ( + "integrity", + { + "description": ( + "Optional parameters for configuring integrity " + "metadata pre-allocation" + ), + "args": [ + ( + "--journal-size", + { + "help": ( + "Size of integrity device's journal. " + "Each block is written to this journal " + "before being written to its address." + ), + "type": parse_range, + }, + ), + ( + "--tag-size", + { + "help": ( + "Size of tag to use to verify " + "correctness of 4KiB block, e.g, 64B. " + "Must be less than 128B." + ), + "type": parse_bytes_range, + }, + ), + ], + }, + ), ], "args": [ ("pool_name", {"help": "Name of new pool"}), diff --git a/src/stratis_cli/_parser/_range.py b/src/stratis_cli/_parser/_range.py index c70d8c2d7..d09cdc156 100644 --- a/src/stratis_cli/_parser/_range.py +++ b/src/stratis_cli/_parser/_range.py @@ -56,11 +56,13 @@ def _unit_map(unit_specifier): assert False, f'Unknown unit specifier "{unit_specifier}"' -def parse_range(values): +def parse_range(values, *, bound=None): """ Parse a range value. :param str values: string to parse + :param bound: upper bound on the Range value + :type bound: Range """ match = _RANGE_RE.search(values) if match is None: @@ -76,9 +78,22 @@ def parse_range(values): assert result.magnitude.denominator == 1 + if bound is not None: + if bound < result: + raise argparse.ArgumentTypeError( + f"Specified size {result} is at least upper bound {bound}." + ) + return result +def parse_bytes_range(values): + """ + Parse a range that must be less than 128B. + """ + return parse_range(values, bound=Range(128)) + + class RejectAction(argparse.Action): """ Just reject any use of the option. diff --git a/tests/whitebox/integration/test_parser.py b/tests/whitebox/integration/test_parser.py index 141d7f39e..bc01e5b2c 100644 --- a/tests/whitebox/integration/test_parser.py +++ b/tests/whitebox/integration/test_parser.py @@ -221,6 +221,20 @@ def test_create_with_post_parser_set(self): for prefix in [[], ["--propagate"]]: self.check_system_exit(prefix + command_line, _PARSE_ERROR) + def test_create_with_oversize_tag_value(self): + """ + Verify that a tag value of at least 128B will result in a parser error. + """ + command_line = [ + "pool", + "create", + "pn", + "/dev/n", + "--tag-size=128B", + ] + for prefix in [[], ["--propagate"]]: + self.check_system_exit(prefix + command_line, _PARSE_ERROR) + def test_stratis_list_filesystem_with_name_no_pool(self): """ We want to get a parse error if filesystem UUID is specified but no