docs: add clan options search page
This provides a simpler and more intuitive search over a flat list of possible options. Styling still to be improved
This commit is contained in:
@@ -179,6 +179,7 @@ nav:
|
|||||||
- 04-fetching-nix-from-python: decisions/04-fetching-nix-from-python.md
|
- 04-fetching-nix-from-python: decisions/04-fetching-nix-from-python.md
|
||||||
- 05-deployment-parameters: decisions/05-deployment-parameters.md
|
- 05-deployment-parameters: decisions/05-deployment-parameters.md
|
||||||
- Template: decisions/_template.md
|
- Template: decisions/_template.md
|
||||||
|
- Options: options.md
|
||||||
|
|
||||||
docs_dir: site
|
docs_dir: site
|
||||||
site_dir: out
|
site_dir: out
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
asciinema-player-css,
|
asciinema-player-css,
|
||||||
roboto,
|
roboto,
|
||||||
fira-code,
|
fira-code,
|
||||||
|
docs-options,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
@@ -55,5 +56,6 @@ pkgs.stdenv.mkDerivation {
|
|||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
cp -a out/ $out/
|
cp -a out/ $out/
|
||||||
|
cp -r ${docs-options} $out/options-page
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
{ inputs, self, ... }:
|
{ inputs, self, ... }:
|
||||||
{
|
{
|
||||||
|
imports = [
|
||||||
|
./options/flake-module.nix
|
||||||
|
];
|
||||||
perSystem =
|
perSystem =
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
@@ -124,7 +127,7 @@
|
|||||||
packages = {
|
packages = {
|
||||||
docs = pkgs.python3.pkgs.callPackage ./default.nix {
|
docs = pkgs.python3.pkgs.callPackage ./default.nix {
|
||||||
clan-core = self;
|
clan-core = self;
|
||||||
inherit (self'.packages) clan-cli-docs inventory-api-docs;
|
inherit (self'.packages) clan-cli-docs docs-options inventory-api-docs;
|
||||||
inherit (inputs) nixpkgs;
|
inherit (inputs) nixpkgs;
|
||||||
inherit module-docs;
|
inherit module-docs;
|
||||||
inherit asciinema-player-js;
|
inherit asciinema-player-js;
|
||||||
|
|||||||
167
docs/nix/options/flake-module.nix
Normal file
167
docs/nix/options/flake-module.nix
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
{ self, config, ... }:
|
||||||
|
{
|
||||||
|
perSystem =
|
||||||
|
{
|
||||||
|
inputs',
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
mapAttrsToList
|
||||||
|
flip
|
||||||
|
mapAttrs
|
||||||
|
mkOption
|
||||||
|
types
|
||||||
|
splitString
|
||||||
|
stringLength
|
||||||
|
substring
|
||||||
|
;
|
||||||
|
inherit (self) clanLib;
|
||||||
|
|
||||||
|
serviceModules = self.clan.modules;
|
||||||
|
|
||||||
|
baseHref = "/options-page/";
|
||||||
|
|
||||||
|
evalService =
|
||||||
|
serviceModule:
|
||||||
|
lib.evalModules {
|
||||||
|
modules = [
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
serviceModule
|
||||||
|
../../../lib/inventory/distributed-service/service-module.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
getRoles = module: (evalService module).config.roles;
|
||||||
|
|
||||||
|
getManifest = module: (evalService module).config.manifest;
|
||||||
|
|
||||||
|
loadFile = file: if builtins.pathExists file then builtins.readFile file else "";
|
||||||
|
|
||||||
|
settingsModules =
|
||||||
|
module: flip mapAttrs (getRoles module) (_roleName: roleConfig: roleConfig.interface);
|
||||||
|
|
||||||
|
# Map each letter to its capitalized version
|
||||||
|
capitalizeChar =
|
||||||
|
char:
|
||||||
|
{
|
||||||
|
a = "A";
|
||||||
|
b = "B";
|
||||||
|
c = "C";
|
||||||
|
d = "D";
|
||||||
|
e = "E";
|
||||||
|
f = "F";
|
||||||
|
g = "G";
|
||||||
|
h = "H";
|
||||||
|
i = "I";
|
||||||
|
j = "J";
|
||||||
|
k = "K";
|
||||||
|
l = "L";
|
||||||
|
m = "M";
|
||||||
|
n = "N";
|
||||||
|
o = "O";
|
||||||
|
p = "P";
|
||||||
|
q = "Q";
|
||||||
|
r = "R";
|
||||||
|
s = "S";
|
||||||
|
t = "T";
|
||||||
|
u = "U";
|
||||||
|
v = "V";
|
||||||
|
w = "W";
|
||||||
|
x = "X";
|
||||||
|
y = "Y";
|
||||||
|
z = "Z";
|
||||||
|
}
|
||||||
|
.${char};
|
||||||
|
|
||||||
|
title =
|
||||||
|
name:
|
||||||
|
let
|
||||||
|
# split by -
|
||||||
|
parts = splitString "-" name;
|
||||||
|
# capitalize first letter of each part
|
||||||
|
capitalize = part: (capitalizeChar (substring 0 1 part)) + substring 1 (stringLength part) part;
|
||||||
|
capitalizedParts = map capitalize parts;
|
||||||
|
in
|
||||||
|
builtins.concatStringsSep " " capitalizedParts;
|
||||||
|
|
||||||
|
fakeInstanceOptions =
|
||||||
|
name: module:
|
||||||
|
let
|
||||||
|
manifest = getManifest module;
|
||||||
|
description = ''
|
||||||
|
# ${title name} (Clan Service)
|
||||||
|
|
||||||
|
**${manifest.description}**
|
||||||
|
|
||||||
|
${loadFile (module._file + "/../README.md")}
|
||||||
|
|
||||||
|
${
|
||||||
|
if manifest.categories != [ ] then
|
||||||
|
"Categories: " + builtins.concatStringsSep ", " manifest.categories
|
||||||
|
else
|
||||||
|
"No categories defined"
|
||||||
|
}
|
||||||
|
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
_ = mkOption {
|
||||||
|
type = types.raw;
|
||||||
|
};
|
||||||
|
instances.${name} = lib.mkOption {
|
||||||
|
inherit description;
|
||||||
|
type = types.submodule {
|
||||||
|
options.roles = flip mapAttrs (settingsModules module) (
|
||||||
|
roleName: roleSettingsModule:
|
||||||
|
mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
imports = [
|
||||||
|
(import ../../../lib/inventory/build-inventory/roles-interface.nix {
|
||||||
|
inherit clanLib;
|
||||||
|
nestedSettingsOption = mkOption {
|
||||||
|
type = types.raw;
|
||||||
|
description = ''
|
||||||
|
See [instances.${name}.roles.${roleName}.settings](${baseHref}?option_scope=0&option=instances.${name}.roles.${roleName}.settings)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
settingsOption = mkOption {
|
||||||
|
type = types.submoduleWith {
|
||||||
|
modules = [ roleSettingsModule ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mkScope = name: modules: {
|
||||||
|
inherit name;
|
||||||
|
modules = [
|
||||||
|
(import ../../../lib/inventory/build-inventory/interface.nix {
|
||||||
|
inherit clanLib;
|
||||||
|
noInstanceOptions = true;
|
||||||
|
})
|
||||||
|
] ++ mapAttrsToList fakeInstanceOptions modules;
|
||||||
|
urlPrefix = "https://github.com/nix-community/dream2nix/blob/main/";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
packages.docs-options = inputs'.nuschtos.packages.mkMultiSearch {
|
||||||
|
inherit baseHref;
|
||||||
|
title = "Clan Options";
|
||||||
|
# scopes = mapAttrsToList mkScope serviceModules;
|
||||||
|
scopes = [ (mkScope "Clan Inventory" serviceModules) ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
14
docs/overrides/options.html
Normal file
14
docs/overrides/options.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{% extends "base.html" %} {% block extrahead %}
|
||||||
|
<style>
|
||||||
|
.md-main__inner {
|
||||||
|
max-width: 100% !important;
|
||||||
|
}
|
||||||
|
.md-content {
|
||||||
|
max-width: 100% !important;
|
||||||
|
}
|
||||||
|
.md-main__inner {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %} {% block site_nav %}{% endblock %} {% block content %} {{
|
||||||
|
page.content }} {% endblock %}
|
||||||
6
docs/site/options.md
Normal file
6
docs/site/options.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
template: options.html
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
<iframe src="/options-page/" height="1000" width="100%"></iframe>
|
||||||
84
flake.lock
generated
84
flake.lock
generated
@@ -67,6 +67,50 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ixx": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": [
|
||||||
|
"nuschtos",
|
||||||
|
"flake-utils"
|
||||||
|
],
|
||||||
|
"nixpkgs": [
|
||||||
|
"nuschtos",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1748294338,
|
||||||
|
"narHash": "sha256-FVO01jdmUNArzBS7NmaktLdGA5qA3lUMJ4B7a05Iynw=",
|
||||||
|
"owner": "NuschtOS",
|
||||||
|
"repo": "ixx",
|
||||||
|
"rev": "cc5f390f7caf265461d4aab37e98d2292ebbdb85",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NuschtOS",
|
||||||
|
"ref": "v0.0.8",
|
||||||
|
"repo": "ixx",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nix-darwin": {
|
"nix-darwin": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -128,6 +172,28 @@
|
|||||||
"url": "https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz"
|
"url": "https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nuschtos": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"ixx": "ixx",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1749730855,
|
||||||
|
"narHash": "sha256-L3x2nSlFkXkM6tQPLJP3oCBMIsRifhIDPMQQdHO5xWo=",
|
||||||
|
"owner": "NuschtOS",
|
||||||
|
"repo": "search",
|
||||||
|
"rev": "8dfe5879dd009ff4742b668d9c699bc4b9761742",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NuschtOS",
|
||||||
|
"repo": "search",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"data-mesher": "data-mesher",
|
"data-mesher": "data-mesher",
|
||||||
@@ -137,8 +203,9 @@
|
|||||||
"nix-select": "nix-select",
|
"nix-select": "nix-select",
|
||||||
"nixos-facter-modules": "nixos-facter-modules",
|
"nixos-facter-modules": "nixos-facter-modules",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
|
"nuschtos": "nuschtos",
|
||||||
"sops-nix": "sops-nix",
|
"sops-nix": "sops-nix",
|
||||||
"systems": "systems",
|
"systems": "systems_2",
|
||||||
"treefmt-nix": "treefmt-nix"
|
"treefmt-nix": "treefmt-nix"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -177,6 +244,21 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"systems_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"treefmt-nix": {
|
"treefmt-nix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
|||||||
@@ -34,6 +34,9 @@
|
|||||||
treefmt-nix.follows = "treefmt-nix";
|
treefmt-nix.follows = "treefmt-nix";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nuschtos.url = "github:NuschtOS/search";
|
||||||
|
nuschtos.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
{ clanLib }:
|
{
|
||||||
|
clanLib,
|
||||||
|
# workaround for docs rendering to include fake instance options
|
||||||
|
noInstanceOptions ? false,
|
||||||
|
}:
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
config,
|
config,
|
||||||
@@ -370,7 +374,11 @@ in
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
instances = lib.mkOption {
|
instances =
|
||||||
|
if noInstanceOptions then
|
||||||
|
{ }
|
||||||
|
else
|
||||||
|
lib.mkOption {
|
||||||
description = "Multi host service module instances";
|
description = "Multi host service module instances";
|
||||||
type = types.attrsOf (
|
type = types.attrsOf (
|
||||||
types.submoduleWith {
|
types.submoduleWith {
|
||||||
@@ -401,77 +409,12 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
default = { };
|
|
||||||
};
|
};
|
||||||
roles = lib.mkOption {
|
roles = lib.mkOption {
|
||||||
default = { };
|
default = { };
|
||||||
type = types.attrsOf (
|
type = types.attrsOf (
|
||||||
types.submodule {
|
types.submodule {
|
||||||
options = {
|
imports = [ (import ./roles-interface.nix { inherit clanLib; }) ];
|
||||||
# TODO: deduplicate
|
|
||||||
machines = lib.mkOption {
|
|
||||||
type = types.attrsOf (
|
|
||||||
types.submodule {
|
|
||||||
options.settings = lib.mkOption {
|
|
||||||
default = { };
|
|
||||||
type = clanLib.types.uniqueDeferredSerializableModule;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
tags = lib.mkOption {
|
|
||||||
type = types.attrsOf (types.submodule { });
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
settings = lib.mkOption {
|
|
||||||
default = { };
|
|
||||||
type = clanLib.types.uniqueDeferredSerializableModule;
|
|
||||||
};
|
|
||||||
extraModules = lib.mkOption {
|
|
||||||
description = ''
|
|
||||||
List of additionally imported `.nix` expressions.
|
|
||||||
|
|
||||||
Supported types:
|
|
||||||
|
|
||||||
- **Strings**: Interpreted relative to the 'directory' passed to buildClan.
|
|
||||||
- **Paths**: should be relative to the current file.
|
|
||||||
- **Any**: Nix expression must be serializable to JSON.
|
|
||||||
|
|
||||||
!!! Note
|
|
||||||
**The import only happens if the machine is part of the service or role.**
|
|
||||||
|
|
||||||
Other types are passed through to the nixos configuration.
|
|
||||||
|
|
||||||
???+ Example
|
|
||||||
To import the `special.nix` file
|
|
||||||
|
|
||||||
```
|
|
||||||
. Clan Directory
|
|
||||||
├── flake.nix
|
|
||||||
...
|
|
||||||
└── modules
|
|
||||||
├── special.nix
|
|
||||||
└── ...
|
|
||||||
```
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{
|
|
||||||
extraModules = [ "modules/special.nix" ];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
'';
|
|
||||||
apply = value: if lib.isString value then value else builtins.seq (builtins.toJSON value) value;
|
|
||||||
default = [ ];
|
|
||||||
type = types.listOf (
|
|
||||||
types.oneOf [
|
|
||||||
types.str
|
|
||||||
types.path
|
|
||||||
(types.attrsOf types.anything)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -485,6 +428,8 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
services = lib.mkOption {
|
services = lib.mkOption {
|
||||||
|
# services are deprecated in favor of `instances`
|
||||||
|
visible = false;
|
||||||
description = ''
|
description = ''
|
||||||
Services of the inventory.
|
Services of the inventory.
|
||||||
|
|
||||||
|
|||||||
86
lib/inventory/build-inventory/roles-interface.nix
Normal file
86
lib/inventory/build-inventory/roles-interface.nix
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
{
|
||||||
|
clanLib,
|
||||||
|
settingsOption ? null,
|
||||||
|
nestedSettingsOption ? null,
|
||||||
|
}:
|
||||||
|
{ lib, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
types
|
||||||
|
;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
# TODO: deduplicate
|
||||||
|
machines = lib.mkOption {
|
||||||
|
type = types.attrsOf (
|
||||||
|
types.submodule {
|
||||||
|
options.settings =
|
||||||
|
if nestedSettingsOption != null then
|
||||||
|
nestedSettingsOption
|
||||||
|
else
|
||||||
|
lib.mkOption {
|
||||||
|
default = { };
|
||||||
|
type = clanLib.types.uniqueDeferredSerializableModule;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
tags = lib.mkOption {
|
||||||
|
type = types.attrsOf (types.submodule { });
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
settings =
|
||||||
|
if settingsOption != null then
|
||||||
|
settingsOption
|
||||||
|
else
|
||||||
|
lib.mkOption {
|
||||||
|
default = { };
|
||||||
|
type = clanLib.types.uniqueDeferredSerializableModule;
|
||||||
|
};
|
||||||
|
extraModules = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
List of additionally imported `.nix` expressions.
|
||||||
|
|
||||||
|
Supported types:
|
||||||
|
|
||||||
|
- **Strings**: Interpreted relative to the 'directory' passed to buildClan.
|
||||||
|
- **Paths**: should be relative to the current file.
|
||||||
|
- **Any**: Nix expression must be serializable to JSON.
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
**The import only happens if the machine is part of the service or role.**
|
||||||
|
|
||||||
|
Other types are passed through to the nixos configuration.
|
||||||
|
|
||||||
|
???+ Example
|
||||||
|
To import the `special.nix` file
|
||||||
|
|
||||||
|
```
|
||||||
|
. Clan Directory
|
||||||
|
├── flake.nix
|
||||||
|
...
|
||||||
|
└── modules
|
||||||
|
├── special.nix
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
extraModules = [ "modules/special.nix" ];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
'';
|
||||||
|
apply = value: if lib.isString value then value else builtins.seq (builtins.toJSON value) value;
|
||||||
|
default = [ ];
|
||||||
|
type = types.listOf (
|
||||||
|
types.oneOf [
|
||||||
|
types.str
|
||||||
|
types.path
|
||||||
|
(types.attrsOf types.anything)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user