Run formatter

This commit is contained in:
pinpox
2025-08-25 18:40:51 +02:00
parent a9c53b8b1e
commit 41c52197ea
71 changed files with 2118 additions and 1379 deletions

View File

@@ -2,18 +2,24 @@
## Service Module Specification
This section explains how to author a clan service module.
We discussed the initial architecture in [01-clan-service-modules](../../decisions/01-ClanModules.md) and decided to rework the format.
This section explains how to author a clan service module. We discussed the
initial architecture in
[01-clan-service-modules](../../decisions/01-ClanModules.md) and decided to
rework the format.
For the full specification and current state see: **[Service Author Reference](../../reference/clanServices/clan-service-author-interface.md)**
For the full specification and current state see:
**[Service Author Reference](../../reference/clanServices/clan-service-author-interface.md)**
### A Minimal module
First of all we need to register our module into the `clan.modules` attribute. Make sure to choose a unique name so the module doesn't have a name collision with any of the core modules.
First of all we need to register our module into the `clan.modules` attribute.
Make sure to choose a unique name so the module doesn't have a name collision
with any of the core modules.
While not required we recommend to prefix your module attribute name.
If you export the module from your flake, other people will be able to import it and use it within their clan.
If you export the module from your flake, other people will be able to import it
and use it within their clan.
i.e. `@hsjobeki/customNetworking`
@@ -35,8 +41,9 @@ outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } ({
The imported module file must fulfill at least the following requirements:
- Be an actual module. That means: Be either an attribute set; or a function that returns an attribute set.
- Required `_class = "clan.service"
- Be an actual module. That means: Be either an attribute set; or a function
that returns an attribute set.
- Required \`\_class = "clan.service"
- Required `manifest.name = "<name of the provided service>"`
```nix title="/service-modules/networking.nix"
@@ -47,19 +54,28 @@ The imported module file must fulfill at least the following requirements:
}
```
For more attributes see: **[Service Author Reference](../../reference/clanServices/clan-service-author-interface.md)**
For more attributes see:
**[Service Author Reference](../../reference/clanServices/clan-service-author-interface.md)**
### Adding functionality to the module
While the very minimal module is valid in itself it has no way of adding any machines to it, because it doesn't specify any roles.
While the very minimal module is valid in itself it has no way of adding any
machines to it, because it doesn't specify any roles.
The next logical step is to think about the interactions between the machines and define *roles* for them.
The next logical step is to think about the interactions between the machines
and define *roles* for them.
Here is a short guide with some conventions:
- [ ] If they all have the same relation to each other `peer` is commonly used. `peers` can often talk to each other directly.
- [ ] Often machines don't necessarily have direct relation to each other and there is one elevated machine in the middle classically know as `client-server`. `clients` are less likely to talk directly to each other than `peers`
- [ ] If your machines don't have any relation and/or interactions to each other you should reconsider if the desired functionality is really a multi-host service.
- [ ] If they all have the same relation to each other `peer` is commonly used.
`peers` can often talk to each other directly.
- [ ] Often machines don't necessarily have direct relation to each other and
there is one elevated machine in the middle classically know as
`client-server`. `clients` are less likely to talk directly to each other than
`peers`
- [ ] If your machines don't have any relation and/or interactions to each other
you should reconsider if the desired functionality is really a multi-host
service.
```nix title="/service-modules/networking.nix"
{
@@ -145,14 +161,16 @@ Next we need to define the settings and the behavior of these distinct roles.
## Using values from a NixOS machine inside the module
!!! Example "Experimental Status"
This feature is experimental and should be used with care.
!!! Example "Experimental Status" This feature is experimental and should be
used with care.
Sometimes a settings value depends on something within a machines `config`.
Since the `interface` is defined completely machine-agnostic this means values from a machine cannot be set in the traditional way.
Since the `interface` is defined completely machine-agnostic this means values
from a machine cannot be set in the traditional way.
The following example shows how to create a local instance of machine specific settings.
The following example shows how to create a local instance of machine specific
settings.
```nix title="someservice.nix"
{
@@ -174,11 +192,14 @@ The following example shows how to create a local instance of machine specific s
}
```
!!! Danger
`localSettings` are a local attribute. Other machines cannot access it.
If calling extendSettings is done that doesn't change the original `settings` this means if a different machine tries to access i.e `roles.client.settings` it would *NOT* contain your changes.
!!! Danger `localSettings` are a local attribute. Other machines cannot access
it. If calling extendSettings is done that doesn't change the original
`settings` this means if a different machine tries to access i.e
`roles.client.settings` it would *NOT* contain your changes.
Exposing the changed settings to other machines would come with a huge performance penalty, thats why we don't want to offer it.
```
Exposing the changed settings to other machines would come with a huge performance penalty, thats why we don't want to offer it.
```
## Passing `self` or `pkgs` to the module
@@ -189,11 +210,14 @@ In general we found the following two best practices:
1. Using `lib.importApply`
2. Using a wrapper module
Both have pros and cons. After all using `importApply` is the easier one, but might be more limiting sometimes.
Both have pros and cons. After all using `importApply` is the easier one, but
might be more limiting sometimes.
### Using `importApply`
Using [importApply](https://github.com/NixOS/nixpkgs/pull/230588) is essentially the same as `import file` followed by a function-application; but preserves the error location.
Using [importApply](https://github.com/NixOS/nixpkgs/pull/230588) is essentially
the same as `import file` followed by a function-application; but preserves the
error location.
Imagine your module looks like this
@@ -234,7 +258,8 @@ outputs = inputs: flake-parts.lib.mkFlake { inherit inputs; } ({self, lib, ...}:
}
```
Then wrap the module and forward the variable `self` from the outer context into the module
Then wrap the module and forward the variable `self` from the outer context into
the module
```nix title="flake.nix"
# ...
@@ -255,9 +280,10 @@ outputs = inputs: flake-parts.lib.mkFlake { inherit inputs; } ({self, lib, ...}:
})
```
The benefit of this approach is that downstream users can override the value of `myClan` by using `mkForce` or other priority modifiers.
The benefit of this approach is that downstream users can override the value of
`myClan` by using `mkForce` or other priority modifiers.
---
______________________________________________________________________
## Further