clan-config: init

- nixos-modules to jsonschema converter
- nix unit testing via adisbladis/nix-unit
- clan config: configuration CLI for nixos-modules
This commit is contained in:
DavHau
2023-08-02 20:04:16 +02:00
parent 5268ecb595
commit b88ac7a2bf
12 changed files with 668 additions and 26 deletions

View File

@@ -0,0 +1,17 @@
{
"name": "John Doe",
"age": 42,
"isAdmin": false,
"kernelModules": [
"usbhid",
"usb_storage"
],
"userIds": {
"mic92": 1,
"lassulus": 2,
"davhau": 3
},
"services": {
"opt": "this option doesn't make sense"
}
}

View File

@@ -0,0 +1,46 @@
/*
An example nixos module declaring an interface.
*/
{ lib, ... }: {
options = {
name = lib.mkOption {
type = lib.types.str;
default = "John Doe";
description = "The name of the user";
};
age = lib.mkOption {
type = lib.types.int;
default = 42;
description = "The age of the user";
};
isAdmin = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Is the user an admin?";
};
# a submodule option
services = lib.mkOption {
type = lib.types.submodule {
options.opt = lib.mkOption {
type = lib.types.str;
default = "foo";
description = "A submodule option";
};
};
};
userIds = lib.mkOption {
type = lib.types.attrsOf lib.types.int;
description = "Some attributes";
default = {
horst = 1;
peter = 2;
albrecht = 3;
};
};
kernelModules = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ "nvme" "xhci_pci" "ahci" ];
description = "A list of enabled kernel modules";
};
};
}

View File

@@ -0,0 +1,54 @@
{
"type": "object",
"properties": {
"name": {
"type": "string",
"default": "John Doe",
"description": "The name of the user"
},
"age": {
"type": "integer",
"default": 42,
"description": "The age of the user"
},
"isAdmin": {
"type": "boolean",
"default": false,
"description": "Is the user an admin?"
},
"kernelModules": {
"type": "array",
"items": {
"type": "string"
},
"default": [
"nvme",
"xhci_pci",
"ahci"
],
"description": "A list of enabled kernel modules"
},
"userIds": {
"type": "object",
"default": {
"horst": 1,
"peter": 2,
"albrecht": 3
},
"additionalProperties": {
"type": "integer"
},
"description": "Some attributes"
},
"services": {
"type": "object",
"properties": {
"opt": {
"type": "string",
"default": "foo",
"description": "A submodule option"
}
}
}
}
}

View File

@@ -0,0 +1,8 @@
# run these tests via `nix-unit ./test.nix`
{ lib ? (import <nixpkgs> { }).lib
, slib ? import ../../clan_cli/config/schema-lib.nix { inherit lib; }
}:
{
parseOption = import ./test_parseOption.nix { inherit lib slib; };
parseOptions = import ./test_parseOptions.nix { inherit lib slib; };
}

View File

@@ -0,0 +1,249 @@
# tests for the nixos options to jsonschema converter
# run these tests via `nix-unit ./test.nix`
{ lib ? (import <nixpkgs> { }).lib
, slib ? import ../../clan_cli/config/schema-lib.nix { inherit lib; }
}:
let
description = "Test Description";
evalType = type: default:
let
evaledConfig = lib.evalModules {
modules = [{
options.opt = lib.mkOption {
inherit type;
inherit default;
inherit description;
};
}];
};
in
evaledConfig.options.opt;
in
{
testNoDefaultNoDescription =
let
evaledConfig = lib.evalModules {
modules = [{
options.opt = lib.mkOption {
type = lib.types.bool;
};
}];
};
in
{
expr = slib.parseOption evaledConfig.options.opt;
expected = {
type = "boolean";
};
};
testBool =
let
default = false;
in
{
expr = slib.parseOption (evalType lib.types.bool default);
expected = {
type = "boolean";
inherit default description;
};
};
testString =
let
default = "hello";
in
{
expr = slib.parseOption (evalType lib.types.str default);
expected = {
type = "string";
inherit default description;
};
};
testInteger =
let
default = 42;
in
{
expr = slib.parseOption (evalType lib.types.int default);
expected = {
type = "integer";
inherit default description;
};
};
testFloat =
let
default = 42.42;
in
{
expr = slib.parseOption (evalType lib.types.float default);
expected = {
type = "number";
inherit default description;
};
};
testEnum =
let
default = "foo";
values = [ "foo" "bar" "baz" ];
in
{
expr = slib.parseOption (evalType (lib.types.enum values) default);
expected = {
enum = values;
inherit default description;
};
};
testListOfInt =
let
default = [ 1 2 3 ];
in
{
expr = slib.parseOption (evalType (lib.types.listOf lib.types.int) default);
expected = {
type = "array";
items = {
type = "integer";
};
inherit default description;
};
};
testAttrsOfInt =
let
default = { foo = 1; bar = 2; baz = 3; };
in
{
expr = slib.parseOption (evalType (lib.types.attrsOf lib.types.int) default);
expected = {
type = "object";
additionalProperties = {
type = "integer";
};
inherit default description;
};
};
testNullOrBool =
let
default = null; # null is a valid value for this type
in
{
expr = slib.parseOption (evalType (lib.types.nullOr lib.types.bool) default);
expected = {
type = [ "null" "boolean" ];
inherit default description;
};
};
testSubmoduleOption =
let
subModule = {
options.opt = lib.mkOption {
type = lib.types.bool;
default = true;
inherit description;
};
};
in
{
expr = slib.parseOption (evalType (lib.types.submodule subModule) { });
expected = {
type = "object";
properties = {
opt = {
type = "boolean";
default = true;
inherit description;
};
};
};
};
testSubmoduleOptionWithoutDefault =
let
subModule = {
options.opt = lib.mkOption {
type = lib.types.bool;
inherit description;
};
};
in
{
expr = slib.parseOption (evalType (lib.types.submodule subModule) { });
expected = {
type = "object";
properties = {
opt = {
type = "boolean";
inherit description;
};
};
required = [ "opt" ];
};
};
testAttrsOfSubmodule =
let
subModule = {
options.opt = lib.mkOption {
type = lib.types.bool;
default = true;
inherit description;
};
};
default = { foo.opt = false; bar.opt = true; };
in
{
expr = slib.parseOption (evalType (lib.types.attrsOf (lib.types.submodule subModule)) default);
expected = {
type = "object";
additionalProperties = {
type = "object";
properties = {
opt = {
type = "boolean";
default = true;
inherit description;
};
};
};
inherit default description;
};
};
testListOfSubmodule =
let
subModule = {
options.opt = lib.mkOption {
type = lib.types.bool;
default = true;
inherit description;
};
};
default = [{ opt = false; } { opt = true; }];
in
{
expr = slib.parseOption (evalType (lib.types.listOf (lib.types.submodule subModule)) default);
expected = {
type = "array";
items = {
type = "object";
properties = {
opt = {
type = "boolean";
default = true;
inherit description;
};
};
};
inherit default description;
};
};
}

View File

@@ -0,0 +1,20 @@
# tests for the nixos options to jsonschema converter
# run these tests via `nix-unit ./test.nix`
{ lib ? (import <nixpkgs> { }).lib
, slib ? import ../../clan_cli/config/schema-lib.nix { inherit lib; }
}:
let
evaledOptions =
let
evaledConfig = lib.evalModules {
modules = [ ./example-interface.nix ];
};
in
evaledConfig.options;
in
{
testParseOptions = {
expr = slib.parseOptions evaledOptions;
expected = builtins.fromJSON (builtins.readFile ./example-schema.json);
};
}