Merge branch 'yaml-schemata' into calamares
This commit is contained in:
commit
066acdbbc6
116
ci/configvalidator.py
Normal file
116
ci/configvalidator.py
Normal file
@ -0,0 +1,116 @@
|
||||
#! /usr/bin/env python3
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
# License-Filename: LICENSES/BSD2
|
||||
#
|
||||
usage = """
|
||||
Validates a Calamares config file -- YAML syntax -- against a schema.
|
||||
|
||||
The schema is also written in YAML syntax, but the schema itself
|
||||
is JSON-schema. This is possible because all JSON is YAML, and most
|
||||
YAML is JSON. The limited subset of YAML that Calamares uses is
|
||||
JSON-representable, anyway.
|
||||
|
||||
Usage:
|
||||
configvalidator.py <schema> <file> ...
|
||||
"""
|
||||
|
||||
# The schemata originally lived outside the Calamares repository,
|
||||
# without documented tooling. By putting them in the repository
|
||||
# with the example files and explicit tooling, there's a better
|
||||
# chance of them catching problems and acting as documentation.
|
||||
|
||||
dependencies = """
|
||||
Dependencies for this tool are: py-yaml and py-jsonschema.
|
||||
|
||||
https://pyyaml.org/
|
||||
https://github.com/Julian/jsonschema
|
||||
|
||||
Simple installation is `pip install pyyaml jsonschema`
|
||||
"""
|
||||
|
||||
ERR_IMPORT, ERR_USAGE, ERR_FILE_NOT_FOUND, ERR_SYNTAX, ERR_INVALID = range(1,6)
|
||||
|
||||
### DEPENDENCIES
|
||||
#
|
||||
#
|
||||
try:
|
||||
from jsonschema import validate, SchemaError, ValidationError
|
||||
from yaml import safe_load, YAMLError
|
||||
except ImportError as e:
|
||||
print(e)
|
||||
print(dependencies)
|
||||
exit(ERR_IMPORT)
|
||||
|
||||
from os.path import exists
|
||||
import sys
|
||||
|
||||
### INPUT VALIDATION
|
||||
#
|
||||
#
|
||||
if len(sys.argv) < 3:
|
||||
print(usage)
|
||||
exit(ERR_USAGE)
|
||||
|
||||
schema_file_name = sys.argv[1]
|
||||
config_file_names = sys.argv[2:]
|
||||
|
||||
if not exists(schema_file_name):
|
||||
print(usage)
|
||||
print("\nSchema file '{}' does not exist.".format(schema_file_name))
|
||||
exit(ERR_FILE_NOT_FOUND)
|
||||
for f in config_file_names:
|
||||
if not exists(f):
|
||||
print(usage)
|
||||
print("\nYAML file '{}' does not exist.".format(f))
|
||||
exit(ERR_FILE_NOT_FOUND)
|
||||
|
||||
### FILES SYNTAX CHECK
|
||||
#
|
||||
#
|
||||
with open(schema_file_name, "r") as data:
|
||||
try:
|
||||
schema = safe_load(data)
|
||||
except YAMLError as e:
|
||||
print("Schema error: {} {}.".format(e.problem, e.problem_mark))
|
||||
print("\nSchema file '{}' is invalid YAML.".format(schema_file_name))
|
||||
exit(ERR_SYNTAX)
|
||||
|
||||
try:
|
||||
validate(instance={}, schema=schema)
|
||||
# While developing the schemata, get full exceptions from schema failure
|
||||
except SchemaError as e:
|
||||
print(e)
|
||||
print("\nSchema file '{}' is invalid JSON-Schema.".format(schema_file_name))
|
||||
exit(ERR_INVALID)
|
||||
except ValidationError:
|
||||
# Just means that empty isn't valid, but the Schema itself is
|
||||
pass
|
||||
|
||||
configs = []
|
||||
for f in config_file_names:
|
||||
config = None
|
||||
with open(f, "r") as data:
|
||||
try:
|
||||
config = safe_load(data)
|
||||
except YAMLError as e:
|
||||
print("YAML error: {} {}.".format(e.problem, e.problem_mark))
|
||||
print("\nYAML file '{}' is invalid.".format(f))
|
||||
exit(ERR_SYNTAX)
|
||||
if config is None:
|
||||
print("YAML file '{}' is empty.".format(f))
|
||||
configs.append(config)
|
||||
|
||||
assert len(configs) == len(config_file_names), "Not all configurations loaded."
|
||||
|
||||
### SCHEMA VALIDATION
|
||||
#
|
||||
#
|
||||
for c, f in zip(configs, config_file_names):
|
||||
try:
|
||||
validate(instance=c, schema=schema)
|
||||
except ValidationError as e:
|
||||
print(e)
|
||||
print("\nConfig file '{}' does not validate in schema.".format(f))
|
||||
exit(ERR_INVALID)
|
@ -66,3 +66,21 @@ endforeach()
|
||||
|
||||
include( CalamaresAddTranslations )
|
||||
add_calamares_python_translations( ${CALAMARES_TRANSLATION_LANGUAGES} )
|
||||
|
||||
# TODO:3.3: Use FindPython3
|
||||
if ( BUILD_TESTING AND PYTHONINTERP_FOUND AND PYTHON_EXECUTABLE )
|
||||
# The tests for each config file are independent of whether the
|
||||
# module is enabled or not: the config file should match its schema
|
||||
# regardless.
|
||||
foreach( SUBDIRECTORY ${SUBDIRECTORIES} )
|
||||
set( _schema_file "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/${SUBDIRECTORY}.schema.yaml" )
|
||||
set( _conf_file "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/${SUBDIRECTORY}.conf" )
|
||||
if ( EXISTS "${_schema_file}" AND EXISTS "${_conf_file}" )
|
||||
add_test(
|
||||
NAME validate-${SUBDIRECTORY}
|
||||
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_SOURCE_DIR}/ci/configvalidator.py" "${_schema_file}" "${_conf_file}"
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
|
18
src/modules/bootloader/bootloader.schema.yaml
Normal file
18
src/modules/bootloader/bootloader.schema.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/bootloader
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
efiBootLoader: { type: string, required: true }
|
||||
kernel: { type: string, required: true }
|
||||
img: { type: string, required: true }
|
||||
fallback: { type: str }
|
||||
timeout: { type: str }
|
||||
bootloaderEntryName: { type: str }
|
||||
kernelLine: { type: str }
|
||||
fallbackKernelLine: { type: str }
|
||||
grubInstall: { type: string, required: true }
|
||||
grubMkconfig: { type: string, required: true }
|
||||
grubCfg: { type: string, required: true }
|
||||
efiBootloaderId: { type: str }
|
16
src/modules/displaymanager/displaymanager.schema.yaml
Normal file
16
src/modules/displaymanager/displaymanager.schema.yaml
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/displaymanager
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
"displaymanagers":
|
||||
type: seq
|
||||
sequence:
|
||||
- { type: string, required: true, enum: [slim, sddm, lightdm, gdm, mdm, lxdm, kdm] }
|
||||
"defaultDesktopEnvironment":
|
||||
type: map
|
||||
mapping:
|
||||
"executable": { type: str }
|
||||
"desktopFile": { type: str }
|
||||
"basicSetup": { type: boolean, default: false }
|
11
src/modules/finished/finished.schema.yaml
Normal file
11
src/modules/finished/finished.schema.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/finished
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
restartNowEnabled: { type: boolean, default: true } # TODO:3.3: remove
|
||||
restartNowChecked: { type: boolean, default: false } # TODO:3.3: remove
|
||||
restartNowCommand: { type: string }
|
||||
restartNowMode: { type: string, enum: [ never, user-unchecked, user-checked, always ] }
|
||||
notifyOnFinished: { type: boolean }
|
19
src/modules/fstab/fstab.schema.yaml
Normal file
19
src/modules/fstab/fstab.schema.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/fstab
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
"mountOptions":
|
||||
type: map
|
||||
mapping:
|
||||
"default": { type: string, required: true }
|
||||
"btrfs": { type: string, required: true }
|
||||
"ssdExtraMountOptions":
|
||||
type: map
|
||||
mapping:
|
||||
"ext4": { type: string, required: true }
|
||||
"jfs": { type: string, required: true }
|
||||
"xfs": { type: string, required: true }
|
||||
"swap": { type: string, required: true }
|
||||
"btrfs": { type: string, required: true }
|
15
src/modules/grubcfg/grubcfg.schema.yaml
Normal file
15
src/modules/grubcfg/grubcfg.schema.yaml
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/grubcfg
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
"overwrite": { type: boolean, default: false }
|
||||
"defaults":
|
||||
type: map
|
||||
mapping:
|
||||
"GRUB_TIMEOUT": { type: int, required: true }
|
||||
"GRUB_DEFAULT": { type: string, required: true }
|
||||
"GRUB_DISABLE_SUBMENU": { type: boolean, default: true }
|
||||
"GRUB_TERMINAL_OUTPUT": { type: string, required: true }
|
||||
"GRUB_DISABLE_RECOVERY": { type: boolean, default: true }
|
7
src/modules/initcpio/initcpio.schema.yaml
Normal file
7
src/modules/initcpio/initcpio.schema.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/initcpio
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
kernel: { type: string, required: true }
|
8
src/modules/keyboard/keyboard.schema.yaml
Normal file
8
src/modules/keyboard/keyboard.schema.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/finished
|
||||
additionalProperties: keyboard
|
||||
type: object
|
||||
properties:
|
||||
xOrgConfFileName: { type: string, required: true }
|
||||
convertedKeymapPath: { type: string, required: true }
|
17
src/modules/license/license.schema.yaml
Normal file
17
src/modules/license/license.schema.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/license
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
"entries":
|
||||
type: seq
|
||||
sequence:
|
||||
- type: map
|
||||
mapping:
|
||||
"id": { type: str }
|
||||
"name": { type: str }
|
||||
"vendor": { type: str }
|
||||
"type": { type: str }
|
||||
"url": { type: str }
|
||||
"required": { type: boolean, default: false }
|
10
src/modules/locale/locale.schema.yaml
Normal file
10
src/modules/locale/locale.schema.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/locale
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
"region": { type: str }
|
||||
"zone": { type: str }
|
||||
"localeGenPath": { type: string, required: true }
|
||||
"geoipUrl": { type: str }
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/luksopenswaphookcfg
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
"configFilePath": { type: string, required: true }
|
9
src/modules/machineid/machineid.schema.yaml
Normal file
9
src/modules/machineid/machineid.schema.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/machineid
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
"systemd": { type: boolean, default: true }
|
||||
"dbus": { type: boolean, default: true }
|
||||
"symlink": { type: boolean, default: true }
|
24
src/modules/mount/mount.schema.yaml
Normal file
24
src/modules/mount/mount.schema.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/mount
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
"extraMounts":
|
||||
type: seq
|
||||
sequence:
|
||||
- type: map
|
||||
mapping:
|
||||
"device": { type: string, required: true }
|
||||
"fs": { type: str }
|
||||
"mountPoint": { type: string, required: true }
|
||||
"options": { type: str }
|
||||
"extraMountsEfi":
|
||||
type: seq
|
||||
sequence:
|
||||
- type: map
|
||||
mapping:
|
||||
"device": { type: string, required: true }
|
||||
"fs": { type: str }
|
||||
"mountPoint": { type: string, required: true }
|
||||
"options": { type: str }
|
7
src/modules/netinstall/netinstall.schema.yaml
Normal file
7
src/modules/netinstall/netinstall.schema.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/netinstall
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
groupsUrl: { type: string, required: true }
|
33
src/modules/packages/packages.schema.yaml
Normal file
33
src/modules/packages/packages.schema.yaml
Normal file
@ -0,0 +1,33 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/packages
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
"backend": { type: string, required: true, enum: [packagekit, zypp, yum, dnf, urpmi, apt, pacman, portage, entropy] }
|
||||
"update_db": { type: boolean, default: true }
|
||||
"operations":
|
||||
type: seq
|
||||
sequence:
|
||||
- type: map
|
||||
mapping:
|
||||
"install":
|
||||
type: seq
|
||||
sequence:
|
||||
- { type: text }
|
||||
"remove":
|
||||
type: seq
|
||||
sequence:
|
||||
- { type: text }
|
||||
"localInstall":
|
||||
type: seq
|
||||
sequence:
|
||||
- { type: text }
|
||||
"try_install":
|
||||
type: seq
|
||||
sequence:
|
||||
- { type: text }
|
||||
"try_remove":
|
||||
type: seq
|
||||
sequence:
|
||||
- { type: text }
|
11
src/modules/partition/partition.schema.yaml
Normal file
11
src/modules/partition/partition.schema.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/partition
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
efiSystemPartition: { type: string, required: true }
|
||||
ensureSuspendToDisk: { type: boolean, default: true }
|
||||
drawNestedPartitions: { type: boolean, default: false }
|
||||
alwaysShowPartitionLabels: { type: boolean, default: true }
|
||||
defaultFileSystemType: { type: string, required: true }
|
7
src/modules/plymouthcfg/plymouthcfg.schema.yaml
Normal file
7
src/modules/plymouthcfg/plymouthcfg.schema.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/plymouthcfg
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
plymouth_theme: { type: str }
|
7
src/modules/removeuser/removeuser.schema.yaml
Normal file
7
src/modules/removeuser/removeuser.schema.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/removeuser
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
"username": { type: string, required: true }
|
8
src/modules/umount/umount.schema.yaml
Normal file
8
src/modules/umount/umount.schema.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/umount
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
"srcLog": { type: str }
|
||||
"destLog": { type: str }
|
14
src/modules/unpackfs/unpackfs.schema.yaml
Normal file
14
src/modules/unpackfs/unpackfs.schema.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/unpackfs
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
"unpack":
|
||||
type: seq
|
||||
sequence:
|
||||
- type: map
|
||||
mapping:
|
||||
"source": { type: string, required: true }
|
||||
"sourcefs": { type: str }
|
||||
"destination": { type: str }
|
18
src/modules/users/users.schema.yaml
Normal file
18
src/modules/users/users.schema.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/users
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
"defaultGroups":
|
||||
required: true
|
||||
type: seq
|
||||
sequence:
|
||||
- { type: str }
|
||||
"autologinGroup": { type: string, required: true }
|
||||
"doAutologin": { type: boolean, default: true }
|
||||
"sudoersGroup": { type: string, required: true }
|
||||
"setRootPassword": { type: boolean, default: true }
|
||||
"availableShells": { type: str }
|
||||
"avatarFilePath": { type: str }
|
||||
"doReusePassword": { type: boolean, default: true }
|
36
src/modules/welcome/welcome.schema.yaml
Normal file
36
src/modules/welcome/welcome.schema.yaml
Normal file
@ -0,0 +1,36 @@
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/welcome
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
# TODO:3.3: drop the string alternatives and put the URL part in Branding
|
||||
showSupportUrl: { anyOf: [ { type: boolean, default: true }, { type: string } ] }
|
||||
showKnownIssuesUrl: { anyOf: [ { type: boolean, default: true }, { type: string } ] }
|
||||
showReleaseNotesUrl: { anyOf: [ { type: boolean, default: true }, { type: string } ] }
|
||||
showDonateUrl: { anyOf: [ { type: boolean, default: true }, { type: string } ] }
|
||||
|
||||
requirements:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
requiredStorage: { type: number }
|
||||
requiredRam: { type: number }
|
||||
internetCheckUrl: { type: string }
|
||||
check:
|
||||
type: array
|
||||
items: { type: string, enum: [storage, ram, power, internet, root, screen], unique: true }
|
||||
required: # Key-name in the config-file
|
||||
type: array
|
||||
items: { type: string, enum: [storage, ram, power, internet, root, screen], unique: true }
|
||||
required: [ requiredStorage, requiredRam, check ] # Schema keyword
|
||||
|
||||
# TODO: refactor, this is reused in locale
|
||||
geoip:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
style: { type: string, enum: [ none, fixed, xml, json ] }
|
||||
url: { type: string }
|
||||
selector: { type: string }
|
||||
required: [ style, url, selector ]
|
Loading…
Reference in New Issue
Block a user