Run formatter
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user