how to write a module
This commit is contained in:
parent
0a2588013a
commit
dd0b1734c1
1 changed files with 106 additions and 3 deletions
|
@ -150,7 +150,110 @@ meaning that it won't be started until that other service is up.
|
||||||
Module implementation
|
Module implementation
|
||||||
*********************
|
*********************
|
||||||
|
|
||||||
TODO: make your own modules
|
Modules in Liminix conventionally live in
|
||||||
|
:file:`modules/somename/default.nix`. If you want or need to
|
||||||
|
write your own, you may wish to refer to the
|
||||||
|
examples there in conjunction with reading this section.
|
||||||
|
|
||||||
* how a module exposes services
|
A module is a function that accepts ``{lib, pkgs, config, ... }`` and
|
||||||
* defining types
|
returns an attrset with keys ``imports, options config``.
|
||||||
|
|
||||||
|
* ``imports`` is a list of paths to the other modules required by this one
|
||||||
|
|
||||||
|
* ``options`` is a nested set of option declarations
|
||||||
|
|
||||||
|
* ``config`` is a nested set of option definitions
|
||||||
|
|
||||||
|
The NixOS manual section `Writing NixOS Modules
|
||||||
|
<https://nixos.org/manual/nixos/stable/#sec-writing-modules>`_ is a
|
||||||
|
quite comprehensive reference to writing NixOS modules, which is also
|
||||||
|
mostly applicable to Liminix except that it doesn't cover
|
||||||
|
service templates.
|
||||||
|
|
||||||
|
Service templates
|
||||||
|
=================
|
||||||
|
|
||||||
|
To expose a service template in a module, it needs the following:
|
||||||
|
|
||||||
|
* an option declaration for ``system.service.myservicename`` with the
|
||||||
|
type of ``liminix.lib.types.serviceDefn``
|
||||||
|
|
||||||
|
.. code-block:: nix
|
||||||
|
|
||||||
|
options = {
|
||||||
|
system.service.cowsay = mkOption {
|
||||||
|
type = liminix.lib.types.serviceDefn;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
* an option definition for the same key, which specifies where to
|
||||||
|
import the service template from (often :file:`./service.nix`)
|
||||||
|
and the types of its parameters.
|
||||||
|
|
||||||
|
.. code-block:: nix
|
||||||
|
|
||||||
|
config.system.service.cowsay = liminix.callService ./service.nix {
|
||||||
|
address = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "0.0.0.0";
|
||||||
|
description = "Listen on specified address";
|
||||||
|
example = "127.0.0.1";
|
||||||
|
};
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 22;
|
||||||
|
description = "Listen on specified TCP port";
|
||||||
|
};
|
||||||
|
breed = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "British Friesian"
|
||||||
|
description = "Breed of the cow";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Then you need to provide the service template itself, probably in
|
||||||
|
:file:`./service.nix`:
|
||||||
|
|
||||||
|
.. code-block:: nix
|
||||||
|
|
||||||
|
{
|
||||||
|
# any nixpkgs package can be named here
|
||||||
|
liminix
|
||||||
|
, cowsayd
|
||||||
|
, serviceFns
|
||||||
|
, lib
|
||||||
|
}:
|
||||||
|
# these are the parameters declared in the callService invocation
|
||||||
|
{ address, port, breed} :
|
||||||
|
let
|
||||||
|
inherit (liminix.services) longrun;
|
||||||
|
inherit (lib.strings) escapeShellArg;
|
||||||
|
in longrun {
|
||||||
|
name = "cowsayd";
|
||||||
|
run = "${cowsayd}/bin/cowsayd --address ${address} --port ${builtins.toString port} --breed ${escapeShellArg breed}";
|
||||||
|
}
|
||||||
|
|
||||||
|
.. tip::
|
||||||
|
|
||||||
|
Not relevant to module-based services specifically, but a common
|
||||||
|
gotcha when specifiying services is forgetting to transform "rich"
|
||||||
|
parameter values into text when composing a command for the shell
|
||||||
|
to execute. Note here that the port number, an integer, is
|
||||||
|
stringified with ``toString``, and the name of the breed,
|
||||||
|
which may contain spaces, is
|
||||||
|
escaped with ``escapeShellArg``
|
||||||
|
|
||||||
|
Types
|
||||||
|
=====
|
||||||
|
|
||||||
|
All of the NixOS module types are available in Liminix. These
|
||||||
|
Liminix-specific types also exist in ``pkgs.liminix.lib.types``:
|
||||||
|
|
||||||
|
* ``service``: an s6-rc service
|
||||||
|
* ``interface``: an s6-rc service which specifies a network
|
||||||
|
interface
|
||||||
|
* ``serviceDefn``: a service "template" definition
|
||||||
|
|
||||||
|
In the future it is likely that we will extend this to include other
|
||||||
|
useful types in the networking domain: for example; IP address,
|
||||||
|
network prefix or netmask, protocol family ...
|
||||||
|
|
Loading…
Reference in a new issue