Merge pull request 'Add toml frontmatter description to jsonschema' (#1664) from hsjobeki/clan-core:hsjobeki-main into main
All checks were successful
deploy / deploy-docs (push) Successful in 21s
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.aarch64-darwin.nixos-flash-installer Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-iso-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-iso-installer 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-app-no-breakpoints Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-bash Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-fakeroot Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-e2fsprogs Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-age Build done.
buildbot/nix-build .#checks.x86_64-linux.check-for-breakpoints Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-app-pytest Build done.
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.x86_64-linux.borgbackup Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-apk Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-archlinux Build done.
buildbot/nix-build .#checks.x86_64-linux."clan-dep-python3.11-mypy" Build done.
buildbot/nix-build .#checks.x86_64-linux."clan-dep-python3.11-qemu" 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.clan-dep-sshpass Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-git Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-app Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-inventory-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-default Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-inventory-eval 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.devShell-webview-ui Build done.
buildbot/nix-build .#checks.x86_64-linux.container Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-inventory-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-example-valid Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.matrix-synapse Build done.
buildbot/nix-build .#checks.x86_64-linux.module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.flash Build done.
buildbot/nix-build .#checks.x86_64-linux.package-impure-checks Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.package-merge-after-ci 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-zerotier-members Build done.
buildbot/nix-build .#checks.x86_64-linux.deltachat Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli-docs 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.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.x86_64-linux.package-webview-ui 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.renderClanOptions Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.package-function-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-app Build done.
buildbot/nix-build .#checks.x86_64-linux.package-deploy-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.postgresql Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.secrets Build done.
buildbot/nix-build .#checks.x86_64-linux.package-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-iso-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.template-minimal Build done.
buildbot/nix-build .#checks.x86_64-linux.package-iso-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.test-backups Build done.
buildbot/nix-build .#checks.x86_64-linux.treefmt Build done.
buildbot/nix-build .#checks.x86_64-linux.zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.syncthing Build done.
buildbot/nix-build .#checks.x86_64-linux.wayland-proxy-virtwl 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.
checks / checks-impure (push) Successful in 2m14s

This commit is contained in:
clan-bot 2024-06-26 15:22:48 +00:00
commit 27b0d18f0d
13 changed files with 262 additions and 72 deletions

View File

@ -8,7 +8,6 @@
evalClanModules = import ./eval-clan-modules { inherit clan-core nixpkgs lib; }; evalClanModules = import ./eval-clan-modules { inherit clan-core nixpkgs lib; };
inventory = import ./inventory { inherit lib clan-core; }; inventory = import ./inventory { inherit lib clan-core; };
jsonschema = import ./jsonschema { inherit lib; }; jsonschema = import ./jsonschema { inherit lib; };
# TODO: migrate to also use toml frontmatter modules = import ./description.nix { inherit clan-core lib; };
# modules = import ./description.nix { inherit clan-core lib; };
buildClan = import ./build-clan { inherit clan-core lib nixpkgs; }; buildClan = import ./build-clan { inherit clan-core lib nixpkgs; };
} }

View File

@ -1,33 +1,34 @@
{ ... }: { clan-core, lib }:
rec { rec {
# getReadme = getReadme =
# modulename: modulename:
# let let
# readme = "${clan-core}/clanModules/${modulename}/README.md"; readme = "${clan-core}/clanModules/${modulename}/README.md";
# readmeContents = readmeContents =
# if (builtins.pathExists readme) then if (builtins.pathExists readme) then
# (builtins.readFile readme) (builtins.readFile readme)
# else else
# throw "No README.md found for module ${modulename}"; throw "No README.md found for module ${modulename}";
# in in
# readmeContents; readmeContents;
# getShortDescription = getShortDescription =
# modulename: modulename:
# let let
# content = (getReadme modulename); content = getReadme modulename;
# parts = lib.splitString "---" content; parts = lib.splitString "---" content;
# description = builtins.head parts; # Partition the parts into the first part (the readme content) and the rest (the metadata)
# number_of_newlines = builtins.length (lib.splitString "\n" description); parsed = builtins.partition ({ index, ... }: if index >= 2 then false else true) (
# in lib.filter ({ index, ... }: index != 0) (lib.imap0 (index: part: { inherit index part; }) parts)
# if (builtins.length parts) > 1 then );
# if number_of_newlines > 4 then
# throw "Short description in README.md for module ${modulename} is too long. Max 3 newlines." # Use this if the content is needed
# else if number_of_newlines <= 1 then # readmeContent = lib.concatMapStrings (v: "---" + v.part) parsed.wrong;
# throw "Missing short description in README.md for module ${modulename}."
# else meta = builtins.fromTOML (builtins.head parsed.right).part;
# description in
# else if (builtins.length parts >= 3) then
# throw "Short description delimiter `---` not found in README.md for module ${modulename}"; meta.description
else
throw "Short description delimiter `---` not found in README.md for module ${modulename}";
} }

View File

@ -13,13 +13,18 @@ let
++ (builtins.foldl' ( ++ (builtins.foldl' (
acc: tag: acc: tag:
let let
# For error printing
availableTags = lib.foldlAttrs (
acc: _: v:
v.tags or [ ] ++ acc
) [ ] inventory.machines;
tagMembers = builtins.attrNames ( tagMembers = builtins.attrNames (
lib.filterAttrs (_n: v: builtins.elem tag v.tags or [ ]) inventory.machines lib.filterAttrs (_n: v: builtins.elem tag v.tags or [ ]) inventory.machines
); );
in in
# throw "Machine tag ${tag} not found. Not machine with: tag ${tagName} not in inventory.";
if tagMembers == [ ] then if tagMembers == [ ] then
throw "Machine tag ${tag} not found. Not machine with: tag ${tag} not in inventory." throw "Tag: '${tag}' not found. Available tags: ${builtins.toJSON (lib.unique availableTags)}"
else else
acc ++ tagMembers acc ++ tagMembers
) [ ] members.tags or [ ]); ) [ ] members.tags or [ ]);
@ -76,7 +81,7 @@ let
if builtins.pathExists path then if builtins.pathExists path then
path path
else else
throw "Role doesnt have a module: ${role}. Path: ${path} not found." throw "Module doesn't have role: '${role}'. Path: ${path} not found."
) inverseRoles.${machineName} or [ ]; ) inverseRoles.${machineName} or [ ];
in in
if isInService then if isInService then
@ -101,6 +106,6 @@ let
acc2 acc2
) [ ] serviceConfigs) ) [ ] serviceConfigs)
) [ ] inventory.services ) [ ] inventory.services
) inventory.machines; ) inventory.machines or { };
in in
machines machines

View File

@ -19,6 +19,7 @@ self.lib.buildClan {
machines = { machines = {
"backup_server" = { "backup_server" = {
clan.tags = [ "all" ]; clan.tags = [ "all" ];
# ... rest of the machine config
}; };
"client_1_machine" = { "client_1_machine" = {
clan.tags = [ clan.tags = [

View File

@ -1,47 +1,81 @@
{ ... }: { self, inputs, ... }:
let
inputOverrides = builtins.concatStringsSep " " (
builtins.map (input: " --override-input ${input} ${inputs.${input}}") (builtins.attrNames inputs)
);
in
{ {
flake.inventory = import ./example.nix { inherit self; };
perSystem = perSystem =
{ pkgs, config, ... }:
{ {
packages.inventory-schema = pkgs.stdenv.mkDerivation { pkgs,
name = "inventory-schema"; lib,
src = ./src; config,
system,
buildInputs = [ pkgs.cue ]; ...
}:
installPhase = '' let
mkdir -p $out buildInventory = import ./build-inventory {
''; clan-core = self;
inherit lib;
};
in
{
devShells.inventory-schema = pkgs.mkShell {
inputsFrom = with config.checks; [
lib-inventory-schema
lib-inventory-eval
];
}; };
devShells.inventory-schema = pkgs.mkShell { inputsFrom = [ config.packages.inventory-schema ]; }; # Run: nix-unit --extra-experimental-features flakes --flake .#legacyPackages.x86_64-linux.evalTests
legacyPackages.evalTests = import ./tests {
inherit buildInventory;
clan-core = self;
};
checks.inventory-schema-checks = pkgs.stdenv.mkDerivation { checks = {
name = "inventory-schema-checks"; lib-inventory-eval = pkgs.runCommand "tests" { nativeBuildInputs = [ pkgs.nix-unit ]; } ''
src = ./src; export HOME="$(realpath .)"
buildInputs = [ pkgs.cue ];
buildPhase = ''
echo "Running inventory tests..."
echo "Export cue as json-schema..." nix-unit --eval-store "$HOME" \
cue export --out openapi root.cue --extra-experimental-features flakes \
${inputOverrides} \
echo "Validate test/*.json against inventory-schema..." --flake ${self}#legacyPackages.${system}.evalTests
test_dir="test"
for file in "$test_dir"/*; do
# Check if the item is a file
if [ -f "$file" ]; then
# Print the filename
echo "Running test on: $file"
# Run the cue vet command
cue vet "$file" root.cue -d "#Root"
fi
done
touch $out touch $out
''; '';
lib-inventory-schema = pkgs.stdenv.mkDerivation {
name = "inventory-schema-checks";
src = ./.;
buildInputs = [ pkgs.cue ];
buildPhase = ''
echo "Running inventory tests..."
# Cue is easier to run in the same directory as the schema
cd spec
echo "Export cue as json-schema..."
cue export --out openapi root.cue
echo "Validate test/*.json against inventory-schema..."
test_dir="../examples"
for file in "$test_dir"/*; do
# Check if the item is a file
if [ -f "$file" ]; then
# Print the filename
echo "Running test on: $file"
# Run the cue vet command
cue vet "$file" root.cue -d "#Root"
fi
done
touch $out
'';
};
}; };
}; };
} }

View File

@ -0,0 +1,151 @@
{ buildInventory, clan-core, ... }:
{
test_inventory_empty = {
# Empty inventory should return an empty module
expr = buildInventory { };
expected = { };
};
test_inventory_role_imports =
let
configs = buildInventory {
services = {
borgbackup.instance_1 = {
roles.server.machines = [ "backup_server" ];
roles.client.machines = [
"client_1_machine"
"client_2_machine"
];
};
};
machines = {
"backup_server" = { };
"client_1_machine" = { };
"client_2_machine" = { };
};
};
in
{
expr = {
server_imports = (builtins.head configs."backup_server").imports;
client_1_imports = (builtins.head configs."client_1_machine").imports;
client_2_imports = (builtins.head configs."client_2_machine").imports;
};
expected = {
server_imports = [
clan-core.clanModules.borgbackup
"${clan-core.clanModules.borgbackup}/roles/server.nix"
];
client_1_imports = [
clan-core.clanModules.borgbackup
"${clan-core.clanModules.borgbackup}/roles/client.nix"
];
client_2_imports = [
clan-core.clanModules.borgbackup
"${clan-core.clanModules.borgbackup}/roles/client.nix"
];
};
};
test_inventory_tag_resolve =
let
configs = buildInventory {
services = {
borgbackup.instance_1 = {
roles.client.tags = [ "backup" ];
};
};
machines = {
"not_used_machine" = { };
"client_1_machine" = {
tags = [ "backup" ];
};
"client_2_machine" = {
tags = [ "backup" ];
};
};
};
in
{
expr = {
client_1_machine = builtins.length configs.client_1_machine;
client_2_machine = builtins.length configs.client_2_machine;
not_used_machine = builtins.length configs.not_used_machine;
};
expected = {
client_1_machine = 2;
client_2_machine = 2;
not_used_machine = 0;
};
};
test_inventory_multiple_roles =
let
configs = buildInventory {
services = {
borgbackup.instance_1 = {
roles.client.machines = [ "machine_1" ];
roles.server.machines = [ "machine_1" ];
};
};
machines = {
"machine_1" = { };
};
};
in
{
expr = {
machine_1_imports = (builtins.head configs."machine_1").imports;
};
expected = {
machine_1_imports = [
clan-core.clanModules.borgbackup
"${clan-core.clanModules.borgbackup}/roles/client.nix"
"${clan-core.clanModules.borgbackup}/roles/server.nix"
];
};
};
test_inventory_role_doesnt_exist =
let
configs = buildInventory {
services = {
borgbackup.instance_1 = {
roles.roleXYZ.machines = [ "machine_1" ];
};
};
machines = {
"machine_1" = { };
};
};
in
{
expr = configs;
expectedError = {
type = "ThrownError";
msg = "Module doesn't have role.*";
};
};
test_inventory_tag_doesnt_exist =
let
configs = buildInventory {
services = {
borgbackup.instance_1 = {
roles.client.machines = [ "machine_1" ];
roles.client.tags = [ "tagXYZ" ];
};
};
machines = {
"machine_1" = {
tags = [ "tagABC" ];
};
};
};
in
{
expr = configs;
expectedError = {
type = "ThrownError";
msg = "Tag: '\\w+' not found";
};
};
}

View File

@ -23,8 +23,7 @@
clanModuleFunctionSchemas = lib.mapAttrsFlatten (modulename: _: { clanModuleFunctionSchemas = lib.mapAttrsFlatten (modulename: _: {
name = modulename; name = modulename;
# TODO: migrate to new toml format description = self.lib.modules.getShortDescription modulename;
# description = self.lib.modules.getShortDescription modulename;
parameters = self.lib.jsonschema.parseOptions (optionsFromModule modulename); parameters = self.lib.jsonschema.parseOptions (optionsFromModule modulename);
}) clanModules; }) clanModules;
in in