mirror of https://github.com/cutefishos/calamares
Merge branch 'yaml-schemata' into calamares
commit
066acdbbc6
@ -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)
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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 }
|
@ -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