diff --git a/docs/stratis.txt b/docs/stratis.txt index 1160c4723..35ef19065 100644 --- a/docs/stratis.txt +++ b/docs/stratis.txt @@ -36,8 +36,10 @@ GLOBAL OPTIONS COMMANDS -------- -pool create [--key-desc ] [--clevis <(nbde|tang|tpm2)> [--tang-url ] [<(--thumbprint | --trust-url)>] [--no-overprovision] [..]:: +pool create [--key-desc ] [--clevis <(nbde|tang|tpm2)> [--tang-url ] [<(--thumbprint | --trust-url)>] [--no-overprovision] [--journal-size ] [--tag-spec ] [..]:: Create a pool from one or more block devices, with the given pool name. + The --tag-spec and --journal-size options are used to configure the amount + of space to reserve for integrity metadata. pool stop <(--uuid |--name )>:: Stop a pool, specifying the pool by its UUID or by its name. Tear down the storage stack but leave all metadata intact. diff --git a/src/stratis_cli/_actions/_introspect.py b/src/stratis_cli/_actions/_introspect.py index 0f520d465..6326c2362 100644 --- a/src/stratis_cli/_actions/_introspect.py +++ b/src/stratis_cli/_actions/_introspect.py @@ -13,6 +13,8 @@ + + diff --git a/src/stratis_cli/_actions/_pool.py b/src/stratis_cli/_actions/_pool.py index 8e1a27ca4..f94d1b95a 100644 --- a/src/stratis_cli/_actions/_pool.py +++ b/src/stratis_cli/_actions/_pool.py @@ -199,6 +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) + if namespace.journal_size is None + else (True, namespace.journal_size.magnitude.numerator) + ), + "tag_spec": ( + (False, 0) + if namespace.tag_spec is None + else (True, namespace.tag_spec) + ), }, ) diff --git a/src/stratis_cli/_constants.py b/src/stratis_cli/_constants.py index b8f80e0a8..4a95813c5 100644 --- a/src/stratis_cli/_constants.py +++ b/src/stratis_cli/_constants.py @@ -116,3 +116,16 @@ class Clevis(Enum): def __str__(self): return self.value + + +class IntegrityTagSpec(Enum): + """ + Options for specifying integrity tag size. + """ + + B0 = "0b" + B32 = "32b" + B512 = "512b" + + def __str__(self): + return self.value diff --git a/src/stratis_cli/_parser/_pool.py b/src/stratis_cli/_parser/_pool.py index 27a829783..e78f41c9d 100644 --- a/src/stratis_cli/_parser/_pool.py +++ b/src/stratis_cli/_parser/_pool.py @@ -21,11 +21,17 @@ from uuid import UUID from .._actions import BindActions, PoolActions -from .._constants import Clevis, EncryptionMethod, UnlockMethod, YesOrNo +from .._constants import ( + Clevis, + EncryptionMethod, + IntegrityTagSpec, + UnlockMethod, + YesOrNo, +) 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_range class ClevisEncryptionOptions: # pylint: disable=too-few-public-methods @@ -163,7 +169,46 @@ 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. " + "The size of the journal must be a " + "multiple of 4 KiB." + ), + "type": parse_range, + }, + ), + ( + "--tag-spec", + { + "help": ( + "Integrity tag specification defining " + "the size of the tag used to store a " + "checksum or other value for each " + "block on a device. stratisd chooses " + "a default specification if none is " + "given." + ), + "choices": list(IntegrityTagSpec), + "type": IntegrityTagSpec, + }, + ), + ], + }, + ), ], "args": [ ("pool_name", {"help": "Name of new pool"}), diff --git a/tests/whitebox/integration/test_parser.py b/tests/whitebox/integration/test_parser.py index 141d7f39e..9d92c68bc 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 256B will result in a parser error. + """ + command_line = [ + "pool", + "create", + "pn", + "/dev/n", + "--tag-size=256B", + ] + 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