diff --git a/scale_build/main.py b/scale_build/main.py index 97a196d6..aad63fcf 100644 --- a/scale_build/main.py +++ b/scale_build/main.py @@ -69,7 +69,7 @@ def main(): ) validate_parser = subparsers.add_parser('validate', help='Validate TrueNAS Scale build manifest and system state') - for action in ('manifest', 'system_state'): + for action in ('datasets', 'manifest', 'system_state'): validate_parser.add_argument(f'--validate-{action}', dest=action, action='store_true') validate_parser.add_argument(f'--no-validate-{action}', dest=action, action='store_false') validate_parser.set_defaults(**{action: True}) @@ -93,7 +93,7 @@ def main(): elif args.action == 'clean': complete_cleanup() elif args.action == 'validate': - validate(args.system_state, args.manifest) + validate(args.system_state, args.manifest, args.datasets) elif args.action == 'branchout': validate_branch_out_config(not args.skip_push) branch_out_repos(not args.skip_push) diff --git a/scale_build/validate.py b/scale_build/validate.py index dc212a09..6cf8f509 100644 --- a/scale_build/validate.py +++ b/scale_build/validate.py @@ -1,9 +1,11 @@ import os +import jsonschema import logging import shutil from .exceptions import CallError, MissingPackagesException from .utils.manifest import validate_manifest +from truenas_install import fhs logger = logging.getLogger(__name__) @@ -31,10 +33,18 @@ def validate_system_state(): raise MissingPackagesException(missing_packages) -def validate(system_state_flag=True, manifest_flag=True): +def validate_datasets(): + jsonschema.validate(fhs.TRUENAS_DATASETS, fhs.TRUENAS_DATASET_SCHEMA) + + +def validate(system_state_flag=True, manifest_flag=True, datasets_flag=True): if system_state_flag: validate_system_state() logger.debug('System state Validated') if manifest_flag: validate_manifest() logger.debug('Manifest Validated') + + if datasets_flag: + validate_datasets() + logger.debug('Dataset schema Validated') diff --git a/truenas_install/fhs.py b/truenas_install/fhs.py index 7f714a5b..f2dd4355 100644 --- a/truenas_install/fhs.py +++ b/truenas_install/fhs.py @@ -13,12 +13,16 @@ KEYS -------------- The following keys are supported: -`name` - the name of the dataset (will be appended to other dataset - name related components -`options` - Dataset configuration options (explained below) +`name` - the name of the dataset (will be appended to other dataset name + related components +`options` - Dataset configuration options (explained below). There is no + default. `mode` - permissions to set on the dataset's mountpoint during installation -`mountpoint` - dataset mountpoint. + default is 0o755 +`mountpoint` - dataset mountpoint. If no mountpoint is specified then it + /`name` will be assumed. `snap` - Take a snapshot named "pristine" after creating the dataset. + default is False OPTIONS -------------- @@ -47,6 +51,41 @@ from /usr/local/share/ca-certificates. """ + +# Following schema is used for validation (e.g. "make validate") in scale-build +# If any changes are made to OPTIONS or KEYS above then schema must be updated +# accordingly. +TRUENAS_DATASET_SCHEMA = { + 'type': 'array', + 'items': { + 'type': 'object', + 'properties': { + 'name': {'type': 'string'}, + 'options': { + 'type': 'array', + 'items': { + 'type': 'string', + 'enum': [ + 'NOSUID', + 'NOEXEC', + 'NOACL', + 'NOATIME', + 'RO', + 'NODEV', + ] + }, + 'uniqueItems': True, + }, + 'mode': {'type': 'integer'}, + 'mountpoint': {'type': 'string'}, + 'snap': {'type': 'boolean'}, + }, + 'required': ['name', 'options'], + 'additionalProperties': False, + } +} + + TRUENAS_DATASETS = [ { 'name': 'audit',