Merge pull request 'Json-schema: extend interface by header to allow schema spec and arbitrary extensions' (#1740) from hsjobeki/clan-core:hsjobeki-main into main
All checks were successful
deploy / deploy-docs (push) Successful in 19s
checks / checks-impure (push) Successful in 3m10s
buildbot/nix-build .#checks.aarch64-darwin.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-test-backup Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-minimal-inventory-machine Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-flash-installer Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-minimal-inventory-machine Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-app-no-breakpoints Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-apk Build done.
buildbot/nix-build .#checks.x86_64-linux.check-for-breakpoints Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-deb Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-rpm Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-archlinux Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-age Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-bash Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-e2fsprogs Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-git Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-mypy Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-nix Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-openssh Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-qemu Build done.
buildbot/nix-build .#checks.x86_64-linux.borgbackup Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-inventory-eval Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-app Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-sshpass Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-tor Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-zbar Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-pytest-with-core Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-pytest-without-core Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-app-pytest Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-rsync Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-sops Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-default Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-webview-ui Build done.
buildbot/nix-build .#checks.x86_64-linux.module-clan-vars-eval Build done.
buildbot/nix-build .#checks.x86_64-linux.deltachat Build done.
buildbot/nix-build .#checks.x86_64-linux.matrix-synapse Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-inventory-examples-cue Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-example-valid Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.container Build done.
buildbot/nix-build .#checks.x86_64-linux.module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-app Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.flash Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-inventory-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli-full Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-ts-api Build done.
buildbot/nix-build .#checks.x86_64-linux.package-default Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-nix-unit-tests Build done.
buildbot/nix-build .#checks.x86_64-linux.package-editor Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-impure-checks Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.x86_64-linux.package-merge-after-ci Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-minimal-inventory-machine Build done.
buildbot/nix-build .#checks.x86_64-linux.package-moonlight-sunshine-accept Build done.
buildbot/nix-build .#checks.x86_64-linux.package-pending-reviews Build done.
buildbot/nix-build .#checks.x86_64-linux.package-tea-create-pr Build done.
buildbot/nix-build .#checks.x86_64-linux.package-webview-ui Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zerotier-members Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zerotierone Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.package-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-inventory-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.secrets Build done.
buildbot/nix-build .#checks.x86_64-linux.package-deploy-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.treefmt Build done.
buildbot/nix-build .#checks.x86_64-linux.renderClanOptions Build done.
buildbot/nix-build .#checks.x86_64-linux.postgresql Build done.
buildbot/nix-build .#checks.x86_64-linux.package-function-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.test-backups Build done.
buildbot/nix-build .#checks.x86_64-linux.zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.template-minimal Build done.
buildbot/nix-build .#checks.x86_64-linux.wayland-proxy-virtwl Build done.
buildbot/nix-build .#checks.x86_64-linux.syncthing Build done.
buildbot/nix-build .#checks.x86_64-linux.test-installation Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-install-test-ubuntu-22-04 Build done.
buildbot/nix-eval Build done.
All checks were successful
deploy / deploy-docs (push) Successful in 19s
checks / checks-impure (push) Successful in 3m10s
buildbot/nix-build .#checks.aarch64-darwin.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-test-backup Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-minimal-inventory-machine Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-flash-installer Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-minimal-inventory-machine Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-app-no-breakpoints Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-apk Build done.
buildbot/nix-build .#checks.x86_64-linux.check-for-breakpoints Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-deb Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-rpm Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-archlinux Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-age Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-bash Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-e2fsprogs Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-git Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-mypy Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-nix Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-openssh Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-qemu Build done.
buildbot/nix-build .#checks.x86_64-linux.borgbackup Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-inventory-eval Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-app Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-sshpass Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-tor Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-zbar Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-pytest-with-core Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-pytest-without-core Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-app-pytest Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-rsync Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-sops Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-default Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-webview-ui Build done.
buildbot/nix-build .#checks.x86_64-linux.module-clan-vars-eval Build done.
buildbot/nix-build .#checks.x86_64-linux.deltachat Build done.
buildbot/nix-build .#checks.x86_64-linux.matrix-synapse Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-inventory-examples-cue Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-example-valid Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.container Build done.
buildbot/nix-build .#checks.x86_64-linux.module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-app Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.flash Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-inventory-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli-full Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-ts-api Build done.
buildbot/nix-build .#checks.x86_64-linux.package-default Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-nix-unit-tests Build done.
buildbot/nix-build .#checks.x86_64-linux.package-editor Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-impure-checks Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.x86_64-linux.package-merge-after-ci Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-minimal-inventory-machine Build done.
buildbot/nix-build .#checks.x86_64-linux.package-moonlight-sunshine-accept Build done.
buildbot/nix-build .#checks.x86_64-linux.package-pending-reviews Build done.
buildbot/nix-build .#checks.x86_64-linux.package-tea-create-pr Build done.
buildbot/nix-build .#checks.x86_64-linux.package-webview-ui Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zerotier-members Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zerotierone Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.package-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-inventory-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.secrets Build done.
buildbot/nix-build .#checks.x86_64-linux.package-deploy-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.treefmt Build done.
buildbot/nix-build .#checks.x86_64-linux.renderClanOptions Build done.
buildbot/nix-build .#checks.x86_64-linux.postgresql Build done.
buildbot/nix-build .#checks.x86_64-linux.package-function-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.test-backups Build done.
buildbot/nix-build .#checks.x86_64-linux.zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.template-minimal Build done.
buildbot/nix-build .#checks.x86_64-linux.wayland-proxy-virtwl Build done.
buildbot/nix-build .#checks.x86_64-linux.syncthing Build done.
buildbot/nix-build .#checks.x86_64-linux.test-installation Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-install-test-ubuntu-22-04 Build done.
buildbot/nix-eval Build done.
This commit is contained in:
commit
a1c74c4a10
@ -15,7 +15,7 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
machineRef = lib.mkOptionType {
|
machineRef = lib.mkOptionType {
|
||||||
name = "machineRef";
|
name = "str";
|
||||||
description = "Machine :: [${builtins.concatStringsSep " | " (builtins.attrNames config.machines)}]";
|
description = "Machine :: [${builtins.concatStringsSep " | " (builtins.attrNames config.machines)}]";
|
||||||
check = v: lib.isString v && builtins.elem v (builtins.attrNames config.machines);
|
check = v: lib.isString v && builtins.elem v (builtins.attrNames config.machines);
|
||||||
merge = lib.mergeEqualOption;
|
merge = lib.mergeEqualOption;
|
||||||
@ -29,20 +29,85 @@ let
|
|||||||
);
|
);
|
||||||
|
|
||||||
tagRef = lib.mkOptionType {
|
tagRef = lib.mkOptionType {
|
||||||
name = "tagRef";
|
name = "str";
|
||||||
description = "Tags :: [${builtins.concatStringsSep " | " allTags}]";
|
description = "Tags :: [${builtins.concatStringsSep " | " allTags}]";
|
||||||
check = v: lib.isString v && builtins.elem v allTags;
|
check = v: lib.isString v && builtins.elem v allTags;
|
||||||
merge = lib.mergeEqualOption;
|
merge = lib.mergeEqualOption;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
moduleConfig = lib.mkOption {
|
||||||
|
default = { };
|
||||||
|
type = t.attrsOf t.anything;
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.assertions = lib.mkOption {
|
options = {
|
||||||
type = t.listOf t.unspecified;
|
assertions = lib.mkOption {
|
||||||
internal = true;
|
type = t.listOf t.unspecified;
|
||||||
default = [ ];
|
internal = true;
|
||||||
|
visible = false;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
meta = metaOptions;
|
||||||
|
|
||||||
|
machines = lib.mkOption {
|
||||||
|
default = { };
|
||||||
|
type = t.attrsOf (
|
||||||
|
t.submodule {
|
||||||
|
options = {
|
||||||
|
inherit (metaOptions) name description icon;
|
||||||
|
tags = lib.mkOption {
|
||||||
|
default = [ ];
|
||||||
|
apply = lib.unique;
|
||||||
|
type = t.listOf t.str;
|
||||||
|
};
|
||||||
|
system = lib.mkOption {
|
||||||
|
default = null;
|
||||||
|
type = t.nullOr t.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
services = lib.mkOption {
|
||||||
|
default = { };
|
||||||
|
type = t.attrsOf (
|
||||||
|
t.attrsOf (
|
||||||
|
t.submodule {
|
||||||
|
options.meta = metaOptions;
|
||||||
|
options.config = moduleConfig;
|
||||||
|
options.machines = lib.mkOption {
|
||||||
|
default = { };
|
||||||
|
type = t.attrsOf (t.submodule { options.config = moduleConfig; });
|
||||||
|
};
|
||||||
|
options.roles = lib.mkOption {
|
||||||
|
default = { };
|
||||||
|
type = t.attrsOf (
|
||||||
|
t.submodule {
|
||||||
|
options.machines = lib.mkOption {
|
||||||
|
default = [ ];
|
||||||
|
type = t.listOf machineRef;
|
||||||
|
};
|
||||||
|
options.tags = lib.mkOption {
|
||||||
|
default = [ ];
|
||||||
|
apply = lib.unique;
|
||||||
|
type = t.listOf tagRef;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Smoke validation of the inventory
|
||||||
config.assertions =
|
config.assertions =
|
||||||
let
|
let
|
||||||
|
# Inventory assertions
|
||||||
|
# - All referenced machines must exist in the top-level machines
|
||||||
serviceAssertions = lib.foldlAttrs (
|
serviceAssertions = lib.foldlAttrs (
|
||||||
ass1: serviceName: c:
|
ass1: serviceName: c:
|
||||||
ass1
|
ass1
|
||||||
@ -60,8 +125,11 @@ in
|
|||||||
ass2 ++ assertions
|
ass2 ++ assertions
|
||||||
) [ ] c
|
) [ ] c
|
||||||
) [ ] config.services;
|
) [ ] config.services;
|
||||||
|
|
||||||
|
# Machine assertions
|
||||||
|
# - A machine must define their host system
|
||||||
machineAssertions = map (
|
machineAssertions = map (
|
||||||
{ name, value }:
|
{ name, ... }:
|
||||||
{
|
{
|
||||||
assertion = true;
|
assertion = true;
|
||||||
message = "Machine ${name} should define its host system in the inventory. ()";
|
message = "Machine ${name} should define its host system in the inventory. ()";
|
||||||
@ -69,68 +137,4 @@ in
|
|||||||
) (lib.attrsToList (lib.filterAttrs (_n: v: v.system or null == null) config.machines));
|
) (lib.attrsToList (lib.filterAttrs (_n: v: v.system or null == null) config.machines));
|
||||||
in
|
in
|
||||||
machineAssertions ++ serviceAssertions;
|
machineAssertions ++ serviceAssertions;
|
||||||
|
|
||||||
options.meta = metaOptions;
|
|
||||||
|
|
||||||
options.machines = lib.mkOption {
|
|
||||||
default = { };
|
|
||||||
type = t.attrsOf (
|
|
||||||
t.submodule {
|
|
||||||
options = {
|
|
||||||
inherit (metaOptions) name description icon;
|
|
||||||
tags = lib.mkOption {
|
|
||||||
default = [ ];
|
|
||||||
apply = lib.unique;
|
|
||||||
type = t.listOf t.str;
|
|
||||||
};
|
|
||||||
system = lib.mkOption {
|
|
||||||
default = null;
|
|
||||||
type = t.nullOr t.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
options.services = lib.mkOption {
|
|
||||||
default = { };
|
|
||||||
type = t.attrsOf (
|
|
||||||
t.attrsOf (
|
|
||||||
t.submodule {
|
|
||||||
options.meta = metaOptions;
|
|
||||||
options.config = lib.mkOption {
|
|
||||||
default = { };
|
|
||||||
type = t.anything;
|
|
||||||
};
|
|
||||||
options.machines = lib.mkOption {
|
|
||||||
default = { };
|
|
||||||
type = t.attrsOf (
|
|
||||||
t.submodule {
|
|
||||||
options.config = lib.mkOption {
|
|
||||||
default = { };
|
|
||||||
type = t.anything;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
options.roles = lib.mkOption {
|
|
||||||
default = { };
|
|
||||||
type = t.attrsOf (
|
|
||||||
t.submodule {
|
|
||||||
options.machines = lib.mkOption {
|
|
||||||
default = [ ];
|
|
||||||
type = t.listOf machineRef;
|
|
||||||
};
|
|
||||||
options.tags = lib.mkOption {
|
|
||||||
default = [ ];
|
|
||||||
apply = lib.unique;
|
|
||||||
type = t.listOf tagRef;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
{
|
|
||||||
"machines": {
|
|
||||||
"camina_machine": {
|
|
||||||
"name": "camina"
|
|
||||||
},
|
|
||||||
"vyr_machine": {
|
|
||||||
"name": "vyr"
|
|
||||||
},
|
|
||||||
"vi_machine": {
|
|
||||||
"name": "vi"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"meta": {
|
|
||||||
"name": "kenjis clan"
|
|
||||||
},
|
|
||||||
"services": {
|
|
||||||
"syncthing": {
|
|
||||||
"instance_1": {
|
|
||||||
"meta": {
|
|
||||||
"name": "My sync"
|
|
||||||
},
|
|
||||||
"roles": {
|
|
||||||
"peer": {
|
|
||||||
"machines": ["vyr_machine", "vi_machine", "camina_machine"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"machines": {},
|
|
||||||
"config": {
|
|
||||||
"folders": {
|
|
||||||
"test": {
|
|
||||||
"path": "~/data/docs",
|
|
||||||
"devices": ["camina_machine", "vyr_machine", "vi_machine"]
|
|
||||||
},
|
|
||||||
"videos": {
|
|
||||||
"path": "~/data/videos",
|
|
||||||
"devices": ["camina_machine", "vyr_machine"]
|
|
||||||
},
|
|
||||||
"playlist": {
|
|
||||||
"path": "~/data/playlist",
|
|
||||||
"devices": ["camina_machine", "vi_machine"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
{
|
|
||||||
"machines": {
|
|
||||||
"camina_machine": {
|
|
||||||
"name": "camina"
|
|
||||||
},
|
|
||||||
"vyr_machine": {
|
|
||||||
"name": "vyr"
|
|
||||||
},
|
|
||||||
"vi_machine": {
|
|
||||||
"name": "vi"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"meta": {
|
|
||||||
"name": "kenjis clan"
|
|
||||||
},
|
|
||||||
"services": {
|
|
||||||
"zerotier": {
|
|
||||||
"instance_1": {
|
|
||||||
"meta": {
|
|
||||||
"name": "My Network"
|
|
||||||
},
|
|
||||||
"roles": {
|
|
||||||
"controller": { "machines": ["vyr_machine"] },
|
|
||||||
"moon": { "machines": ["vyr_machine"] },
|
|
||||||
"peer": { "machines": ["vi_machine", "camina_machine"] }
|
|
||||||
},
|
|
||||||
"machines": {
|
|
||||||
"vyr_machine": {
|
|
||||||
"config": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"config": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,16 +21,112 @@ in
|
|||||||
clan-core = self;
|
clan-core = self;
|
||||||
inherit lib;
|
inherit lib;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
optionsFromModule =
|
||||||
|
mName:
|
||||||
|
let
|
||||||
|
eval = self.lib.evalClanModules [ mName ];
|
||||||
|
in
|
||||||
|
if (eval.options.clan ? "${mName}") then eval.options.clan.${mName} else { };
|
||||||
|
|
||||||
|
modulesSchema = lib.mapAttrs (
|
||||||
|
moduleName: _: jsonLib'.parseOptions (optionsFromModule moduleName) { }
|
||||||
|
) self.clanModules;
|
||||||
|
|
||||||
|
jsonLib = self.lib.jsonschema {
|
||||||
|
# includeDefaults = false;
|
||||||
|
};
|
||||||
|
jsonLib' = self.lib.jsonschema {
|
||||||
|
# includeDefaults = false;
|
||||||
|
header = { };
|
||||||
|
};
|
||||||
|
inventorySchema = jsonLib.parseModule (import ./build-inventory/interface.nix);
|
||||||
|
|
||||||
|
getRoles =
|
||||||
|
modulePath:
|
||||||
|
let
|
||||||
|
rolesDir = "${modulePath}/roles";
|
||||||
|
in
|
||||||
|
if builtins.pathExists rolesDir then
|
||||||
|
lib.pipe rolesDir [
|
||||||
|
builtins.readDir
|
||||||
|
(lib.filterAttrs (_n: v: v == "regular"))
|
||||||
|
lib.attrNames
|
||||||
|
(map (fileName: lib.removeSuffix ".nix" fileName))
|
||||||
|
]
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
|
||||||
|
schema = inventorySchema // {
|
||||||
|
properties = inventorySchema.properties // {
|
||||||
|
services = {
|
||||||
|
type = "object";
|
||||||
|
additionalProperties = false;
|
||||||
|
properties = lib.mapAttrs (moduleName: moduleSchema: {
|
||||||
|
type = "object";
|
||||||
|
additionalProperties = {
|
||||||
|
type = "object";
|
||||||
|
additionalProperties = false;
|
||||||
|
properties = {
|
||||||
|
meta =
|
||||||
|
inventorySchema.properties.services.additionalProperties.additionalProperties.properties.meta;
|
||||||
|
config = moduleSchema;
|
||||||
|
roles = {
|
||||||
|
type = "object";
|
||||||
|
additionalProperties = false;
|
||||||
|
required = [ ];
|
||||||
|
properties = lib.listToAttrs (
|
||||||
|
map
|
||||||
|
(role: {
|
||||||
|
name = role;
|
||||||
|
value =
|
||||||
|
inventorySchema.properties.services.additionalProperties.additionalProperties.properties.roles.additionalProperties;
|
||||||
|
})
|
||||||
|
(
|
||||||
|
let
|
||||||
|
roles = getRoles self.clanModules.${moduleName};
|
||||||
|
in
|
||||||
|
if roles == null then [ ] else roles
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
machines =
|
||||||
|
lib.recursiveUpdate
|
||||||
|
inventorySchema.properties.services.additionalProperties.additionalProperties.properties.machines
|
||||||
|
{ additionalProperties.properties.config = moduleSchema; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}) modulesSchema;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
legacyPackages.inventorySchema = schema;
|
||||||
|
|
||||||
devShells.inventory-schema = pkgs.mkShell {
|
devShells.inventory-schema = pkgs.mkShell {
|
||||||
inputsFrom = with config.checks; [
|
inputsFrom = with config.checks; [
|
||||||
lib-inventory-schema
|
lib-inventory-examples-cue
|
||||||
lib-inventory-eval
|
lib-inventory-eval
|
||||||
self'.devShells.default
|
self'.devShells.default
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Inventory schema with concrete module implementations
|
||||||
|
packages.inventory-schema = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "inventory-schema";
|
||||||
|
buildInputs = [ pkgs.cue ];
|
||||||
|
src = ./.;
|
||||||
|
buildPhase = ''
|
||||||
|
export SCHEMA=${builtins.toFile "inventory-schema.json" (builtins.toJSON self'.legacyPackages.inventorySchema)}
|
||||||
|
cp $SCHEMA schema.json
|
||||||
|
cue import -f -p compose -l '#Root:' schema.json
|
||||||
|
mkdir $out
|
||||||
|
cp schema.cue $out
|
||||||
|
cp schema.json $out
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
# Run: nix-unit --extra-experimental-features flakes --flake .#legacyPackages.x86_64-linux.evalTests
|
# Run: nix-unit --extra-experimental-features flakes --flake .#legacyPackages.x86_64-linux.evalTests
|
||||||
legacyPackages.evalTests-inventory = import ./tests {
|
legacyPackages.evalTests-inventory = import ./tests {
|
||||||
inherit buildInventory;
|
inherit buildInventory;
|
||||||
@ -38,32 +134,21 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
checks = {
|
checks = {
|
||||||
lib-inventory-eval = pkgs.runCommand "tests" { nativeBuildInputs = [ pkgs.nix-unit ]; } ''
|
lib-inventory-examples-cue = pkgs.stdenv.mkDerivation {
|
||||||
export HOME="$(realpath .)"
|
|
||||||
|
|
||||||
nix-unit --eval-store "$HOME" \
|
|
||||||
--extra-experimental-features flakes \
|
|
||||||
${inputOverrides} \
|
|
||||||
--flake ${self}#legacyPackages.${system}.evalTests-inventory
|
|
||||||
|
|
||||||
touch $out
|
|
||||||
'';
|
|
||||||
|
|
||||||
lib-inventory-schema = pkgs.stdenv.mkDerivation {
|
|
||||||
name = "inventory-schema-checks";
|
name = "inventory-schema-checks";
|
||||||
src = ./.;
|
src = ./.;
|
||||||
buildInputs = [ pkgs.cue ];
|
buildInputs = [ pkgs.cue ];
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
echo "Running inventory tests..."
|
echo "Running inventory tests..."
|
||||||
# Cue is easier to run in the same directory as the schema
|
# Cue is easier to run in the same directory as the schema
|
||||||
cd spec
|
cp ${self'.packages.inventory-schema}/schema.cue root.cue
|
||||||
|
|
||||||
echo "Export cue as json-schema..."
|
ls -la .
|
||||||
cue export --out openapi root.cue
|
|
||||||
|
|
||||||
echo "Validate test/*.json against inventory-schema..."
|
echo "Validate test/*.json against inventory-schema..."
|
||||||
|
cat root.cue
|
||||||
|
|
||||||
test_dir="../examples"
|
test_dir="./examples"
|
||||||
for file in "$test_dir"/*; do
|
for file in "$test_dir"/*; do
|
||||||
# Check if the item is a file
|
# Check if the item is a file
|
||||||
if [ -f "$file" ]; then
|
if [ -f "$file" ]; then
|
||||||
@ -78,6 +163,16 @@ in
|
|||||||
touch $out
|
touch $out
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
lib-inventory-eval = pkgs.runCommand "tests" { nativeBuildInputs = [ pkgs.nix-unit ]; } ''
|
||||||
|
export HOME="$(realpath .)"
|
||||||
|
|
||||||
|
nix-unit --eval-store "$HOME" \
|
||||||
|
--extra-experimental-features flakes \
|
||||||
|
${inputOverrides} \
|
||||||
|
--flake ${self}#legacyPackages.${system}.evalTests-inventory
|
||||||
|
|
||||||
|
touch $out
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
module: "clan.lol/inventory"
|
|
||||||
language: version: "v0.8.2"
|
|
@ -1,23 +0,0 @@
|
|||||||
package inventory
|
|
||||||
|
|
||||||
import (
|
|
||||||
"clan.lol/inventory/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
@jsonschema(schema="http://json-schema.org/schema#")
|
|
||||||
#Root: {
|
|
||||||
meta: {
|
|
||||||
// A name of the clan (primarily shown by the UI)
|
|
||||||
name: string
|
|
||||||
// A description of the clan
|
|
||||||
description?: string
|
|
||||||
// The icon path
|
|
||||||
icon?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
// // A map of services
|
|
||||||
schema.#service
|
|
||||||
|
|
||||||
// // A map of machines
|
|
||||||
schema.#machine
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package schema
|
|
||||||
|
|
||||||
#machine: machines: [string]: {
|
|
||||||
name: string,
|
|
||||||
description?: string,
|
|
||||||
icon?: string
|
|
||||||
tags: [...string]
|
|
||||||
system?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
#role: string
|
|
||||||
|
|
||||||
#service: services: [string]: [string]: {
|
|
||||||
// Required meta fields
|
|
||||||
meta: {
|
|
||||||
name: string,
|
|
||||||
icon?: string
|
|
||||||
description?: string,
|
|
||||||
},
|
|
||||||
// We moved the machine sepcific config to "machines".
|
|
||||||
// It may be moved back depending on what makes more sense in the future.
|
|
||||||
roles: [#role]: {
|
|
||||||
machines: [...string],
|
|
||||||
tags: [...string],
|
|
||||||
}
|
|
||||||
machines?: {
|
|
||||||
[string]: {
|
|
||||||
config?: {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Global Configuration for the service
|
|
||||||
config?: {
|
|
||||||
// Schema depends on the module.
|
|
||||||
// It declares the interface how the service can be configured.
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +1,16 @@
|
|||||||
{
|
{
|
||||||
lib ? import <nixpkgs/lib>,
|
lib ? import <nixpkgs/lib>,
|
||||||
|
}:
|
||||||
|
{
|
||||||
excludedTypes ? [
|
excludedTypes ? [
|
||||||
"functionTo"
|
"functionTo"
|
||||||
"package"
|
"package"
|
||||||
],
|
],
|
||||||
|
includeDefaults ? true,
|
||||||
|
header ? {
|
||||||
|
"$schema" = "http://json-schema.org/draft-07/schema#";
|
||||||
|
},
|
||||||
|
specialArgs ? { },
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
# remove _module attribute from options
|
# remove _module attribute from options
|
||||||
@ -40,29 +47,41 @@ let
|
|||||||
];
|
];
|
||||||
in
|
in
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
# parses a nixos module to a jsonschema
|
# parses a nixos module to a jsonschema
|
||||||
parseModule =
|
parseModule =
|
||||||
module:
|
module:
|
||||||
let
|
let
|
||||||
evaled = lib.evalModules { modules = [ module ]; };
|
evaled = lib.evalModules {
|
||||||
|
modules = [ module ];
|
||||||
|
inherit specialArgs;
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{ "$schema" = "http://json-schema.org/draft-07/schema#"; } // parseOptions evaled.options;
|
parseOptions evaled.options { };
|
||||||
|
|
||||||
|
parseOptions' = lib.flip parseOptions { addHeader = false; };
|
||||||
|
|
||||||
# parses a set of evaluated nixos options to a jsonschema
|
# parses a set of evaluated nixos options to a jsonschema
|
||||||
parseOptions =
|
parseOptions =
|
||||||
options':
|
options:
|
||||||
|
{
|
||||||
|
# The top-level header object should specify at least the schema version
|
||||||
|
# Can be customized if needed
|
||||||
|
# By default the header is not added to the schema
|
||||||
|
addHeader ? true,
|
||||||
|
}:
|
||||||
let
|
let
|
||||||
options = filterInvisibleOpts (filterExcludedAttrs (clean options'));
|
options' = filterInvisibleOpts (filterExcludedAttrs (clean options));
|
||||||
# parse options to jsonschema properties
|
# parse options to jsonschema properties
|
||||||
properties = lib.mapAttrs (_name: option: parseOption option) options;
|
properties = lib.mapAttrs (_name: option: parseOption option) options';
|
||||||
# TODO: figure out how to handle if prop.anyOf is used
|
# TODO: figure out how to handle if prop.anyOf is used
|
||||||
isRequired = prop: !(prop ? default || prop.type or null == "object");
|
isRequired = prop: !(prop ? default || prop.type or null == "object");
|
||||||
requiredProps = lib.filterAttrs (_: prop: isRequired prop) properties;
|
requiredProps = lib.filterAttrs (_: prop: isRequired prop) properties;
|
||||||
required = lib.optionalAttrs (requiredProps != { }) { required = lib.attrNames requiredProps; };
|
required = lib.optionalAttrs (requiredProps != { }) { required = lib.attrNames requiredProps; };
|
||||||
|
header' = if addHeader then header else { };
|
||||||
in
|
in
|
||||||
# return jsonschema
|
# return jsonschema
|
||||||
required
|
header'
|
||||||
|
// required
|
||||||
// {
|
// {
|
||||||
type = "object";
|
type = "object";
|
||||||
inherit properties;
|
inherit properties;
|
||||||
@ -73,7 +92,7 @@ rec {
|
|||||||
parseOption =
|
parseOption =
|
||||||
option:
|
option:
|
||||||
let
|
let
|
||||||
default = lib.optionalAttrs (option ? default) { inherit (option) default; };
|
default = lib.optionalAttrs (option ? default && includeDefaults) { inherit (option) default; };
|
||||||
example = lib.optionalAttrs (option ? example) {
|
example = lib.optionalAttrs (option ? example) {
|
||||||
examples =
|
examples =
|
||||||
if (builtins.typeOf option.example) == "list" then option.example else [ option.example ];
|
if (builtins.typeOf option.example) == "list" then option.example else [ option.example ];
|
||||||
@ -82,7 +101,6 @@ rec {
|
|||||||
description = option.description.text or option.description;
|
description = option.description.text or option.description;
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
|
||||||
# either type
|
# either type
|
||||||
# TODO: if all nested options are excluded, the parent should be excluded too
|
# TODO: if all nested options are excluded, the parent should be excluded too
|
||||||
if
|
if
|
||||||
@ -104,16 +122,13 @@ rec {
|
|||||||
];
|
];
|
||||||
optionsList = filterExcluded optionsList';
|
optionsList = filterExcluded optionsList';
|
||||||
in
|
in
|
||||||
default // example // description // { anyOf = map parseOption optionsList; }
|
default // example // description // { oneOf = map parseOption optionsList; }
|
||||||
|
|
||||||
# handle nested options (not a submodule)
|
# handle nested options (not a submodule)
|
||||||
else if !option ? _type then
|
else if !option ? _type then
|
||||||
parseOptions option
|
parseOptions' option
|
||||||
|
|
||||||
# throw if not an option
|
# throw if not an option
|
||||||
else if option._type != "option" && option._type != "option-type" then
|
else if option._type != "option" && option._type != "option-type" then
|
||||||
throw "parseOption: not an option"
|
throw "parseOption: not an option"
|
||||||
|
|
||||||
# parse nullOr
|
# parse nullOr
|
||||||
else if
|
else if
|
||||||
option.type.name == "nullOr"
|
option.type.name == "nullOr"
|
||||||
@ -130,32 +145,28 @@ rec {
|
|||||||
// example
|
// example
|
||||||
// description
|
// description
|
||||||
// {
|
// {
|
||||||
anyOf = [
|
oneOf = [
|
||||||
{ type = "null"; }
|
{ type = "null"; }
|
||||||
] ++ (lib.optional (!isExcludedOption nestedOption) (parseOption nestedOption));
|
] ++ (lib.optional (!isExcludedOption nestedOption) (parseOption nestedOption));
|
||||||
}
|
}
|
||||||
|
|
||||||
# parse bool
|
# parse bool
|
||||||
else if
|
else if
|
||||||
option.type.name == "bool"
|
option.type.name == "bool"
|
||||||
# return jsonschema property definition for bool
|
# return jsonschema property definition for bool
|
||||||
then
|
then
|
||||||
default // example // description // { type = "boolean"; }
|
default // example // description // { type = "boolean"; }
|
||||||
|
|
||||||
# parse float
|
# parse float
|
||||||
else if
|
else if
|
||||||
option.type.name == "float"
|
option.type.name == "float"
|
||||||
# return jsonschema property definition for float
|
# return jsonschema property definition for float
|
||||||
then
|
then
|
||||||
default // example // description // { type = "number"; }
|
default // example // description // { type = "number"; }
|
||||||
|
|
||||||
# parse int
|
# parse int
|
||||||
else if
|
else if
|
||||||
(option.type.name == "int" || option.type.name == "positiveInt")
|
(option.type.name == "int" || option.type.name == "positiveInt")
|
||||||
# return jsonschema property definition for int
|
# return jsonschema property definition for int
|
||||||
then
|
then
|
||||||
default // example // description // { type = "integer"; }
|
default // example // description // { type = "integer"; }
|
||||||
|
|
||||||
# TODO: Add support for intMatching in jsonschema
|
# TODO: Add support for intMatching in jsonschema
|
||||||
# parse port type aka. "unsignedInt16"
|
# parse port type aka. "unsignedInt16"
|
||||||
else if
|
else if
|
||||||
@ -165,7 +176,6 @@ rec {
|
|||||||
|| option.type.name == "intBetween"
|
|| option.type.name == "intBetween"
|
||||||
then
|
then
|
||||||
default // example // description // { type = "integer"; }
|
default // example // description // { type = "integer"; }
|
||||||
|
|
||||||
# parse string
|
# parse string
|
||||||
# TODO: parse more precise string types
|
# TODO: parse more precise string types
|
||||||
else if
|
else if
|
||||||
@ -176,51 +186,43 @@ rec {
|
|||||||
# return jsonschema property definition for string
|
# return jsonschema property definition for string
|
||||||
then
|
then
|
||||||
default // example // description // { type = "string"; }
|
default // example // description // { type = "string"; }
|
||||||
|
|
||||||
# TODO: Add support for stringMatching in jsonschema
|
# TODO: Add support for stringMatching in jsonschema
|
||||||
# parse stringMatching
|
# parse stringMatching
|
||||||
else if lib.strings.hasPrefix "strMatching" option.type.name then
|
else if lib.strings.hasPrefix "strMatching" option.type.name then
|
||||||
default // example // description // { type = "string"; }
|
default // example // description // { type = "string"; }
|
||||||
|
|
||||||
# TODO: Add support for separatedString in jsonschema
|
# TODO: Add support for separatedString in jsonschema
|
||||||
else if lib.strings.hasPrefix "separatedString" option.type.name then
|
else if lib.strings.hasPrefix "separatedString" option.type.name then
|
||||||
default // example // description // { type = "string"; }
|
default // example // description // { type = "string"; }
|
||||||
|
|
||||||
# parse string
|
# parse string
|
||||||
else if
|
else if
|
||||||
option.type.name == "path"
|
option.type.name == "path"
|
||||||
# return jsonschema property definition for path
|
# return jsonschema property definition for path
|
||||||
then
|
then
|
||||||
default // example // description // { type = "string"; }
|
default // example // description // { type = "string"; }
|
||||||
|
|
||||||
# parse anything
|
# parse anything
|
||||||
else if
|
else if
|
||||||
option.type.name == "anything"
|
option.type.name == "anything"
|
||||||
# return jsonschema property definition for anything
|
# return jsonschema property definition for anything
|
||||||
then
|
then
|
||||||
default // example // description // { type = allBasicTypes; }
|
default // example // description // { type = allBasicTypes; }
|
||||||
|
|
||||||
# parse unspecified
|
# parse unspecified
|
||||||
else if
|
else if
|
||||||
option.type.name == "unspecified"
|
option.type.name == "unspecified"
|
||||||
# return jsonschema property definition for unspecified
|
# return jsonschema property definition for unspecified
|
||||||
then
|
then
|
||||||
default // example // description // { type = allBasicTypes; }
|
default // example // description // { type = allBasicTypes; }
|
||||||
|
|
||||||
# parse raw
|
# parse raw
|
||||||
else if
|
else if
|
||||||
option.type.name == "raw"
|
option.type.name == "raw"
|
||||||
# return jsonschema property definition for raw
|
# return jsonschema property definition for raw
|
||||||
then
|
then
|
||||||
default // example // description // { type = allBasicTypes; }
|
default // example // description // { type = allBasicTypes; }
|
||||||
|
|
||||||
# parse enum
|
# parse enum
|
||||||
else if
|
else if
|
||||||
option.type.name == "enum"
|
option.type.name == "enum"
|
||||||
# return jsonschema property definition for enum
|
# return jsonschema property definition for enum
|
||||||
then
|
then
|
||||||
default // example // description // { enum = option.type.functor.payload; }
|
default // example // description // { enum = option.type.functor.payload; }
|
||||||
|
|
||||||
# parse listOf submodule
|
# parse listOf submodule
|
||||||
else if
|
else if
|
||||||
option.type.name == "listOf" && option.type.functor.wrapped.name == "submodule"
|
option.type.name == "listOf" && option.type.functor.wrapped.name == "submodule"
|
||||||
@ -231,9 +233,8 @@ rec {
|
|||||||
// description
|
// description
|
||||||
// {
|
// {
|
||||||
type = "array";
|
type = "array";
|
||||||
items = parseOptions (option.type.functor.wrapped.getSubOptions option.loc);
|
items = parseOptions' (option.type.functor.wrapped.getSubOptions option.loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
# parse list
|
# parse list
|
||||||
else if
|
else if
|
||||||
(option.type.name == "listOf")
|
(option.type.name == "listOf")
|
||||||
@ -253,14 +254,12 @@ rec {
|
|||||||
type = "array";
|
type = "array";
|
||||||
}
|
}
|
||||||
// (lib.optionalAttrs (!isExcludedOption nestedOption) { items = parseOption nestedOption; })
|
// (lib.optionalAttrs (!isExcludedOption nestedOption) { items = parseOption nestedOption; })
|
||||||
|
|
||||||
# parse list of unspecified
|
# parse list of unspecified
|
||||||
else if
|
else if
|
||||||
(option.type.name == "listOf") && (option.type.functor.wrapped.name == "unspecified")
|
(option.type.name == "listOf") && (option.type.functor.wrapped.name == "unspecified")
|
||||||
# return jsonschema property definition for list
|
# return jsonschema property definition for list
|
||||||
then
|
then
|
||||||
default // example // description // { type = "array"; }
|
default // example // description // { type = "array"; }
|
||||||
|
|
||||||
# parse attrsOf submodule
|
# parse attrsOf submodule
|
||||||
else if
|
else if
|
||||||
option.type.name == "attrsOf" && option.type.nestedTypes.elemType.name == "submodule"
|
option.type.name == "attrsOf" && option.type.nestedTypes.elemType.name == "submodule"
|
||||||
@ -271,9 +270,8 @@ rec {
|
|||||||
// description
|
// description
|
||||||
// {
|
// {
|
||||||
type = "object";
|
type = "object";
|
||||||
additionalProperties = parseOptions (option.type.nestedTypes.elemType.getSubOptions option.loc);
|
additionalProperties = parseOptions' (option.type.nestedTypes.elemType.getSubOptions option.loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
# parse attrs
|
# parse attrs
|
||||||
else if
|
else if
|
||||||
option.type.name == "attrs"
|
option.type.name == "attrs"
|
||||||
@ -286,7 +284,6 @@ rec {
|
|||||||
type = "object";
|
type = "object";
|
||||||
additionalProperties = true;
|
additionalProperties = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
# parse attrsOf
|
# parse attrsOf
|
||||||
# TODO: if nested option is excluded, the parent sould be excluded too
|
# TODO: if nested option is excluded, the parent sould be excluded too
|
||||||
else if
|
else if
|
||||||
@ -315,15 +312,13 @@ rec {
|
|||||||
else
|
else
|
||||||
false;
|
false;
|
||||||
}
|
}
|
||||||
|
|
||||||
# parse submodule
|
# parse submodule
|
||||||
else if
|
else if
|
||||||
option.type.name == "submodule"
|
option.type.name == "submodule"
|
||||||
# return jsonschema property definition for submodule
|
# return jsonschema property definition for submodule
|
||||||
# then (lib.attrNames (option.type.getSubOptions option.loc).opt)
|
# then (lib.attrNames (option.type.getSubOptions option.loc).opt)
|
||||||
then
|
then
|
||||||
parseOptions (option.type.getSubOptions option.loc)
|
parseOptions' (option.type.getSubOptions option.loc)
|
||||||
|
|
||||||
# throw error if option type is not supported
|
# throw error if option type is not supported
|
||||||
else
|
else
|
||||||
notSupported option;
|
notSupported option;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# run these tests via `nix-unit ./test.nix`
|
# run these tests via `nix-unit ./test.nix`
|
||||||
{
|
{
|
||||||
lib ? (import <nixpkgs> { }).lib,
|
lib ? (import <nixpkgs> { }).lib,
|
||||||
slib ? import ./. { inherit lib; },
|
slib ? (import ./. { inherit lib; } { }),
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
parseOption = import ./test_parseOption.nix { inherit lib slib; };
|
parseOption = import ./test_parseOption.nix { inherit lib slib; };
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# run these tests via `nix-unit ./test.nix`
|
# run these tests via `nix-unit ./test.nix`
|
||||||
{
|
{
|
||||||
lib ? (import <nixpkgs> { }).lib,
|
lib ? (import <nixpkgs> { }).lib,
|
||||||
slib ? import ./. { inherit lib; },
|
slib ? (import ./. { inherit lib; } { }),
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
description = "Test Description";
|
description = "Test Description";
|
||||||
@ -236,7 +236,7 @@ in
|
|||||||
{
|
{
|
||||||
expr = slib.parseOption (evalType (lib.types.nullOr lib.types.bool) default);
|
expr = slib.parseOption (evalType (lib.types.nullOr lib.types.bool) default);
|
||||||
expected = {
|
expected = {
|
||||||
anyOf = [
|
oneOf = [
|
||||||
{ type = "null"; }
|
{ type = "null"; }
|
||||||
{ type = "boolean"; }
|
{ type = "boolean"; }
|
||||||
];
|
];
|
||||||
@ -251,10 +251,10 @@ in
|
|||||||
{
|
{
|
||||||
expr = slib.parseOption (evalType (lib.types.nullOr (lib.types.nullOr lib.types.bool)) default);
|
expr = slib.parseOption (evalType (lib.types.nullOr (lib.types.nullOr lib.types.bool)) default);
|
||||||
expected = {
|
expected = {
|
||||||
anyOf = [
|
oneOf = [
|
||||||
{ type = "null"; }
|
{ type = "null"; }
|
||||||
{
|
{
|
||||||
anyOf = [
|
oneOf = [
|
||||||
{ type = "null"; }
|
{ type = "null"; }
|
||||||
{ type = "boolean"; }
|
{ type = "boolean"; }
|
||||||
];
|
];
|
||||||
@ -386,7 +386,7 @@ in
|
|||||||
{
|
{
|
||||||
expr = slib.parseOption (evalType (lib.types.either lib.types.bool lib.types.str) default);
|
expr = slib.parseOption (evalType (lib.types.either lib.types.bool lib.types.str) default);
|
||||||
expected = {
|
expected = {
|
||||||
anyOf = [
|
oneOf = [
|
||||||
{ type = "boolean"; }
|
{ type = "boolean"; }
|
||||||
{ type = "string"; }
|
{ type = "string"; }
|
||||||
];
|
];
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# run these tests via `nix-unit ./test.nix`
|
# run these tests via `nix-unit ./test.nix`
|
||||||
{
|
{
|
||||||
lib ? (import <nixpkgs> { }).lib,
|
lib ? (import <nixpkgs> { }).lib,
|
||||||
slib ? import ./. { inherit lib; },
|
slib ? (import ./. { inherit lib; } { }),
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
testParseOptions = {
|
testParseOptions = {
|
||||||
@ -17,8 +17,9 @@
|
|||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
expr = slib.parseOptions evaled.options;
|
expr = slib.parseOptions evaled.options { };
|
||||||
expected = {
|
expected = {
|
||||||
|
"$schema" = "http://json-schema.org/draft-07/schema#";
|
||||||
additionalProperties = false;
|
additionalProperties = false;
|
||||||
properties = {
|
properties = {
|
||||||
foo = {
|
foo = {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ options, lib, ... }:
|
{ options, lib, ... }:
|
||||||
let
|
let
|
||||||
jsonschema = import ../../lib/jsonschema { inherit lib; };
|
jsonschema = import ../../lib/jsonschema { inherit lib; } { };
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.clanSchema = lib.mkOption {
|
options.clanSchema = lib.mkOption {
|
||||||
|
@ -94,8 +94,8 @@ def machine_schema(
|
|||||||
++ (map (name: clan-core.clanModules.${{name}}) config.clanImports or []);
|
++ (map (name: clan-core.clanModules.${{name}}) config.clanImports or []);
|
||||||
}};
|
}};
|
||||||
options = fakeMachine.options{"." + ".".join(option_path) if option_path else ""};
|
options = fakeMachine.options{"." + ".".join(option_path) if option_path else ""};
|
||||||
jsonschemaLib = import {Path(__file__).parent / "jsonschema"} {{ inherit lib; }};
|
jsonschemaLib = import {Path(__file__).parent / "jsonschema"} {{ inherit lib; }} {{}};
|
||||||
jsonschema = jsonschemaLib.parseOptions options;
|
jsonschema = jsonschemaLib.parseOptions options {{}};
|
||||||
in
|
in
|
||||||
jsonschema
|
jsonschema
|
||||||
""",
|
""",
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
let
|
let
|
||||||
clanModules = self.clanModules;
|
clanModules = self.clanModules;
|
||||||
|
|
||||||
|
jsonLib = self.lib.jsonschema { };
|
||||||
|
|
||||||
# Uncomment if you only want one module to be available
|
# Uncomment if you only want one module to be available
|
||||||
# clanModules = {
|
# clanModules = {
|
||||||
# borgbackup = self.clanModules.borgbackup;
|
# borgbackup = self.clanModules.borgbackup;
|
||||||
@ -18,13 +20,13 @@
|
|||||||
if (eval.options.clan ? "${mName}") then eval.options.clan.${mName} else { };
|
if (eval.options.clan ? "${mName}") then eval.options.clan.${mName} else { };
|
||||||
|
|
||||||
clanModuleSchemas = lib.mapAttrs (
|
clanModuleSchemas = lib.mapAttrs (
|
||||||
modulename: _: self.lib.jsonschema.parseOptions (optionsFromModule modulename)
|
modulename: _: jsonLib.parseOptions (optionsFromModule modulename) { }
|
||||||
) clanModules;
|
) clanModules;
|
||||||
|
|
||||||
clanModuleFunctionSchemas = lib.mapAttrsFlatten (modulename: _: {
|
clanModuleFunctionSchemas = lib.mapAttrsFlatten (modulename: _: {
|
||||||
name = modulename;
|
name = modulename;
|
||||||
description = self.lib.modules.getShortDescription modulename;
|
description = self.lib.modules.getShortDescription modulename;
|
||||||
parameters = self.lib.jsonschema.parseOptions (optionsFromModule modulename);
|
parameters = jsonLib.parseOptions (optionsFromModule modulename) { };
|
||||||
}) clanModules;
|
}) clanModules;
|
||||||
in
|
in
|
||||||
rec {
|
rec {
|
||||||
|
Loading…
Reference in New Issue
Block a user