lib.module-schema

Library for conversion from NixOS module system options to JSON schema

The NixOS module system makes use of lib.types to validate configurations against the expectations of modules. A configuration that does not satisfy the validation generates a helpful error message. The results are similar to what you might see in a dynamically typed language. Nix is an untyped language. We use the word "type" to refer to attrsets with various attributes, refer to lib.types for more detail, one of these attributes is check, which does the "type checking."

The constraints of these types are not accessible outside of Nix, nor can they be introspected from Nix. This library converts these types and options that make use of them to JSON schema. JSON is convenient to produce from Nix and is easy to process from just about any programming language.

The resulting JSON schema can be used to validate configurations that are not specified in Nix. This makes it possible to produce configuration values from alternative interfaces that trade off expressiveness for simplicity, without losing the validation. An alternative interface doesn't need to convert the configuration to Nix, run a Nix evaluation, collect potential error messages and somehow translate them back to the interface shown to a user. Instead, the interface composes a JSON value, this can be validated against the schema and eventually read into Nix.

The pseudo-type signatures in this library refer to several types that deserve a definition for clarity.

ModuleType
An attrset that conforms to the NixOS module system notion of a type, usually produced by functions in lib.types
ModuleOption
An attrset that conforms to the NixOS module system notion of an option, usually produced by functions in lib.options
JSONSchema
An attrset that when converted with builtins.toJSON results in a valid JSON schema. Note that only optionsToSchema produces a schema suitable as the document root schema object. Other functions do not include a $schema attribute for the convenience of using them as building blocks of a larger schema.

lib.module-schema.optionToSchema

Convert a NixOS module system option to a JSON schema, if data validates against the schema it should be acceptable as a configuration specifying the option.

Inputs

option
NixOS module system option, the result of mkOption

Type

optionToSchema :: ModuleOption -> JSONSchema

Examples

Example

lib.module-schema.optionToSchema usage example

optionToSchema (lib.mkEnableOption "SERVICE")
=> {
     default = false;
     description = "Whether to enable SERVICE.";
     examples = [ true ];
     type = "boolean";
   }
optionToSchema ((nixos {}).options.services.peertube.database.port)
=> {
     default = 5432;
     description = "Database host port.";
     maximum = 65535;
     minimum = 0;
     type = "integer";
   }

lib.module-schema.optionsToSchema

Convert an attribute set of NixOS module system options, i.e., all the options declared for a service, to a JSON schema, if data validates against the schema it should be acceptable as a configuration for the service.

Inputs

options
Attrset of NixOS module system options

Type

optionsToSchema :: Attrs ModuleOption -> JSONSchema

Examples

Example

lib.module-schema.optionsToSchema usage example

optionsToSchema ((nixos {}).options.services.peertube.database)
=> {
     "$schema" = "https://json-schema.org/draft/2020-12/schema";
     createLocally = {
       default = false;
       description = "Configure local PostgreSQL database server for PeerTube.";
       type = "boolean";
     };
     host = {
       default = "if config.services.peertube.database.createLocally\nthen \"/run/postgresql\"\nelse null\n";
       description = "Database host address or unix socket.";
       examples = [ "192.168.15.47" ];
       type = "string";
     };
     name = {
       default = "peertube";
       description = "Database name.";
       type = "string";
     };
     passwordFile = {
       default = null;
       description = "Password for PostgreSQL database.";
       examples = [ "/run/keys/peertube/password-postgresql" ];
       type = [
         "null"
         "string"
       ];
     };
     port = {
       default = 5432;
       description = "Database host port.";
       maximum = 65535;
       minimum = 0;
       type = "integer";
     };
     user = {
       default = "peertube";
       description = "Database user.";
       type = "string";
     };
   }

lib.module-schema.internal

Local bindings can be hard to reach outside of an expression. This set contains attributes used in the implementation of this library, exposing them to tests or users for whom the intended API is not sufficient. There are no guarantees of API stability for these attributes.

This convention is inherited from the Haskell ecosystem.