nixos: nixos/doc/manual/development/writing-modules.xml to CommonMark

Changed files
+363 -192
nixos
+1 -1
nixos/doc/manual/development/development.xml
···
</para>
</partintro>
<xi:include href="../from_md/development/sources.chapter.xml" />
-
<xi:include href="writing-modules.xml" />
+
<xi:include href="../from_md/development/writing-modules.chapter.xml" />
<xi:include href="../from_md/development/building-parts.chapter.xml" />
<xi:include href="../from_md/development/writing-documentation.chapter.xml" />
<xi:include href="../from_md/development/building-nixos.chapter.xml" />
+166
nixos/doc/manual/development/writing-modules.chapter.md
···
+
# Writing NixOS Modules {#sec-writing-modules}
+
+
NixOS has a modular system for declarative configuration. This system
+
combines multiple *modules* to produce the full system configuration.
+
One of the modules that constitute the configuration is
+
`/etc/nixos/configuration.nix`. Most of the others live in the
+
[`nixos/modules`](https://github.com/NixOS/nixpkgs/tree/master/nixos/modules)
+
subdirectory of the Nixpkgs tree.
+
+
Each NixOS module is a file that handles one logical aspect of the
+
configuration, such as a specific kind of hardware, a service, or
+
network settings. A module configuration does not have to handle
+
everything from scratch; it can use the functionality provided by other
+
modules for its implementation. Thus a module can *declare* options that
+
can be used by other modules, and conversely can *define* options
+
provided by other modules in its own implementation. For example, the
+
module
+
[`pam.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/pam.nix)
+
declares the option `security.pam.services` that allows other modules (e.g.
+
[`sshd.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/ssh/sshd.nix))
+
to define PAM services; and it defines the option `environment.etc` (declared by
+
[`etc.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/etc/etc.nix))
+
to cause files to be created in `/etc/pam.d`.
+
+
In [](#sec-configuration-syntax), we saw the following structure of
+
NixOS modules:
+
+
```nix
+
{ config, pkgs, ... }:
+
+
{ option definitions
+
}
+
```
+
+
This is actually an *abbreviated* form of module that only defines
+
options, but does not declare any. The structure of full NixOS modules
+
is shown in [Example: Structure of NixOS Modules](#ex-module-syntax).
+
+
::: {#ex-module-syntax .example}
+
::: {.title}
+
**Example: Structure of NixOS Modules**
+
:::
+
```nix
+
{ config, pkgs, ... }:
+
+
{
+
imports =
+
[ paths of other modules
+
];
+
+
options = {
+
option declarations
+
};
+
+
config = {
+
option definitions
+
};
+
}
+
```
+
:::
+
+
The meaning of each part is as follows.
+
+
- The first line makes the current Nix expression a function. The variable
+
`pkgs` contains Nixpkgs (by default, it takes the `nixpkgs` entry of
+
`NIX_PATH`, see the [Nix manual](https://nixos.org/manual/nix/stable/#sec-common-env)
+
for further details), while `config` contains the full system
+
configuration. This line can be omitted if there is no reference to
+
`pkgs` and `config` inside the module.
+
+
- This `imports` list enumerates the paths to other NixOS modules that
+
should be included in the evaluation of the system configuration. A
+
default set of modules is defined in the file `modules/module-list.nix`.
+
These don\'t need to be added in the import list.
+
+
- The attribute `options` is a nested set of *option declarations*
+
(described below).
+
+
- The attribute `config` is a nested set of *option definitions* (also
+
described below).
+
+
[Example: NixOS Module for the "locate" Service](#locate-example)
+
shows a module that handles the regular update of the "locate" database,
+
an index of all files in the file system. This module declares two
+
options that can be defined by other modules (typically the user's
+
`configuration.nix`): `services.locate.enable` (whether the database should
+
be updated) and `services.locate.interval` (when the update should be done).
+
It implements its functionality by defining two options declared by other
+
modules: `systemd.services` (the set of all systemd services) and
+
`systemd.timers` (the list of commands to be executed periodically by
+
`systemd`).
+
+
::: {#locate-example .example}
+
::: {.title}
+
**Example: NixOS Module for the "locate" Service**
+
:::
+
```nix
+
{ config, lib, pkgs, ... }:
+
+
with lib;
+
+
let
+
cfg = config.services.locate;
+
in {
+
options.services.locate = {
+
enable = mkOption {
+
type = types.bool;
+
default = false;
+
description = ''
+
If enabled, NixOS will periodically update the database of
+
files used by the locate command.
+
'';
+
};
+
+
interval = mkOption {
+
type = types.str;
+
default = "02:15";
+
example = "hourly";
+
description = ''
+
Update the locate database at this interval. Updates by
+
default at 2:15 AM every day.
+
+
The format is described in
+
systemd.time(7).
+
'';
+
};
+
+
# Other options omitted for documentation
+
};
+
+
config = {
+
systemd.services.update-locatedb =
+
{ description = "Update Locate Database";
+
path = [ pkgs.su ];
+
script =
+
''
+
mkdir -m 0755 -p $(dirname ${toString cfg.output})
+
exec updatedb \
+
--localuser=${cfg.localuser} \
+
${optionalString (!cfg.includeStore) "--prunepaths='/nix/store'"} \
+
--output=${toString cfg.output} ${concatStringsSep " " cfg.extraFlags}
+
'';
+
};
+
+
systemd.timers.update-locatedb = mkIf cfg.enable
+
{ description = "Update timer for locate database";
+
partOf = [ "update-locatedb.service" ];
+
wantedBy = [ "timers.target" ];
+
timerConfig.OnCalendar = cfg.interval;
+
};
+
};
+
}
+
```
+
:::
+
+
```{=docbook}
+
<xi:include href="option-declarations.section.xml" />
+
<xi:include href="option-types.section.xml" />
+
<xi:include href="option-def.section.xml" />
+
<xi:include href="assertions.section.xml" />
+
<xi:include href="meta-attributes.section.xml" />
+
<xi:include href="importing-modules.section.xml" />
+
<xi:include href="replace-modules.section.xml" />
+
<xi:include href="freeform-modules.section.xml" />
+
<xi:include href="settings-options.section.xml" />
+
```
-191
nixos/doc/manual/development/writing-modules.xml
···
-
<chapter xmlns="http://docbook.org/ns/docbook"
-
xmlns:xlink="http://www.w3.org/1999/xlink"
-
xmlns:xi="http://www.w3.org/2001/XInclude"
-
version="5.0"
-
xml:id="sec-writing-modules">
-
<title>Writing NixOS Modules</title>
-
<para>
-
NixOS has a modular system for declarative configuration. This system
-
combines multiple <emphasis>modules</emphasis> to produce the full system
-
configuration. One of the modules that constitute the configuration is
-
<filename>/etc/nixos/configuration.nix</filename>. Most of the others live in
-
the
-
<link
-
xlink:href="https://github.com/NixOS/nixpkgs/tree/master/nixos/modules"><filename>nixos/modules</filename></link>
-
subdirectory of the Nixpkgs tree.
-
</para>
-
<para>
-
Each NixOS module is a file that handles one logical aspect of the
-
configuration, such as a specific kind of hardware, a service, or network
-
settings. A module configuration does not have to handle everything from
-
scratch; it can use the functionality provided by other modules for its
-
implementation. Thus a module can <emphasis>declare</emphasis> options that
-
can be used by other modules, and conversely can <emphasis>define</emphasis>
-
options provided by other modules in its own implementation. For example, the
-
module
-
<link
-
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/pam.nix"><filename>pam.nix</filename></link>
-
declares the option <option>security.pam.services</option> that allows other
-
modules (e.g.
-
<link
-
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/ssh/sshd.nix"><filename>sshd.nix</filename></link>)
-
to define PAM services; and it defines the option
-
<option>environment.etc</option> (declared by
-
<link
-
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/etc/etc.nix"><filename>etc.nix</filename></link>)
-
to cause files to be created in <filename>/etc/pam.d</filename>.
-
</para>
-
<para xml:id="para-module-syn">
-
In <xref
-
linkend="sec-configuration-syntax"/>, we saw the following structure
-
of NixOS modules:
-
<programlisting>
-
{ config, pkgs, ... }:
-
-
{ <replaceable>option definitions</replaceable>
-
}
-
</programlisting>
-
This is actually an <emphasis>abbreviated</emphasis> form of module that only
-
defines options, but does not declare any. The structure of full NixOS
-
modules is shown in <xref linkend='ex-module-syntax' />.
-
</para>
-
<example xml:id='ex-module-syntax'>
-
<title>Structure of NixOS Modules</title>
-
<programlisting>
-
{ config, pkgs, ... }: <co xml:id='module-syntax-1' />
-
-
{
-
imports =
-
[ <replaceable>paths of other modules</replaceable> <co xml:id='module-syntax-2' />
-
];
-
-
options = {
-
<replaceable>option declarations</replaceable> <co xml:id='module-syntax-3' />
-
};
-
-
config = {
-
<replaceable>option definitions</replaceable> <co xml:id='module-syntax-4' />
-
};
-
}</programlisting>
-
</example>
-
<para>
-
The meaning of each part is as follows.
-
<calloutlist>
-
<callout arearefs='module-syntax-1'>
-
<para>
-
This line makes the current Nix expression a function. The variable
-
<varname>pkgs</varname> contains Nixpkgs (by default, it takes the
-
<varname>nixpkgs</varname> entry of <envar>NIX_PATH</envar>, see the <link
-
xlink:href="https://nixos.org/manual/nix/stable/#sec-common-env">Nix
-
manual</link> for further details), while <varname>config</varname>
-
contains the full system configuration. This line can be omitted if there
-
is no reference to <varname>pkgs</varname> and <varname>config</varname>
-
inside the module.
-
</para>
-
</callout>
-
<callout arearefs='module-syntax-2'>
-
<para>
-
This list enumerates the paths to other NixOS modules that should be
-
included in the evaluation of the system configuration. A default set of
-
modules is defined in the file
-
<filename>modules/module-list.nix</filename>. These don't need to be added
-
in the import list.
-
</para>
-
</callout>
-
<callout arearefs='module-syntax-3'>
-
<para>
-
The attribute <varname>options</varname> is a nested set of
-
<emphasis>option declarations</emphasis> (described below).
-
</para>
-
</callout>
-
<callout arearefs='module-syntax-4'>
-
<para>
-
The attribute <varname>config</varname> is a nested set of
-
<emphasis>option definitions</emphasis> (also described below).
-
</para>
-
</callout>
-
</calloutlist>
-
</para>
-
<para>
-
<xref linkend='locate-example' /> shows a module that handles the regular
-
update of the “locate” database, an index of all files in the file
-
system. This module declares two options that can be defined by other modules
-
(typically the user’s <filename>configuration.nix</filename>):
-
<option>services.locate.enable</option> (whether the database should be
-
updated) and <option>services.locate.interval</option> (when the update
-
should be done). It implements its functionality by defining two options
-
declared by other modules: <option>systemd.services</option> (the set of all
-
systemd services) and <option>systemd.timers</option> (the list of commands
-
to be executed periodically by <command>systemd</command>).
-
</para>
-
<example xml:id='locate-example'>
-
<title>NixOS Module for the “locate” Service</title>
-
<programlisting>
-
{ config, lib, pkgs, ... }:
-
-
with lib;
-
-
let
-
cfg = config.services.locate;
-
in {
-
options.services.locate = {
-
enable = mkOption {
-
type = types.bool;
-
default = false;
-
description = ''
-
If enabled, NixOS will periodically update the database of
-
files used by the <command>locate</command> command.
-
'';
-
};
-
-
interval = mkOption {
-
type = types.str;
-
default = "02:15";
-
example = "hourly";
-
description = ''
-
Update the locate database at this interval. Updates by
-
default at 2:15 AM every day.
-
-
The format is described in
-
<citerefentry><refentrytitle>systemd.time</refentrytitle>
-
<manvolnum>7</manvolnum></citerefentry>.
-
'';
-
};
-
-
# Other options omitted for documentation
-
};
-
-
config = {
-
systemd.services.update-locatedb =
-
{ description = "Update Locate Database";
-
path = [ pkgs.su ];
-
script =
-
''
-
mkdir -m 0755 -p $(dirname ${toString cfg.output})
-
exec updatedb \
-
--localuser=${cfg.localuser} \
-
${optionalString (!cfg.includeStore) "--prunepaths='/nix/store'"} \
-
--output=${toString cfg.output} ${concatStringsSep " " cfg.extraFlags}
-
'';
-
};
-
-
systemd.timers.update-locatedb = mkIf cfg.enable
-
{ description = "Update timer for locate database";
-
partOf = [ "update-locatedb.service" ];
-
wantedBy = [ "timers.target" ];
-
timerConfig.OnCalendar = cfg.interval;
-
};
-
};
-
}
-
</programlisting>
-
</example>
-
<xi:include href="../from_md/development/option-declarations.section.xml" />
-
<xi:include href="../from_md/development/option-types.section.xml" />
-
<xi:include href="../from_md/development/option-def.section.xml" />
-
<xi:include href="../from_md/development/assertions.section.xml" />
-
<xi:include href="../from_md/development/meta-attributes.section.xml" />
-
<xi:include href="../from_md/development/importing-modules.section.xml" />
-
<xi:include href="../from_md/development/replace-modules.section.xml" />
-
<xi:include href="../from_md/development/freeform-modules.section.xml" />
-
<xi:include href="../from_md/development/settings-options.section.xml" />
-
</chapter>
+196
nixos/doc/manual/from_md/development/writing-modules.chapter.xml
···
+
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude" xml:id="sec-writing-modules">
+
<title>Writing NixOS Modules</title>
+
<para>
+
NixOS has a modular system for declarative configuration. This
+
system combines multiple <emphasis>modules</emphasis> to produce the
+
full system configuration. One of the modules that constitute the
+
configuration is <literal>/etc/nixos/configuration.nix</literal>.
+
Most of the others live in the
+
<link xlink:href="https://github.com/NixOS/nixpkgs/tree/master/nixos/modules"><literal>nixos/modules</literal></link>
+
subdirectory of the Nixpkgs tree.
+
</para>
+
<para>
+
Each NixOS module is a file that handles one logical aspect of the
+
configuration, such as a specific kind of hardware, a service, or
+
network settings. A module configuration does not have to handle
+
everything from scratch; it can use the functionality provided by
+
other modules for its implementation. Thus a module can
+
<emphasis>declare</emphasis> options that can be used by other
+
modules, and conversely can <emphasis>define</emphasis> options
+
provided by other modules in its own implementation. For example,
+
the module
+
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/pam.nix"><literal>pam.nix</literal></link>
+
declares the option <literal>security.pam.services</literal> that
+
allows other modules (e.g.
+
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/ssh/sshd.nix"><literal>sshd.nix</literal></link>)
+
to define PAM services; and it defines the option
+
<literal>environment.etc</literal> (declared by
+
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/etc/etc.nix"><literal>etc.nix</literal></link>)
+
to cause files to be created in <literal>/etc/pam.d</literal>.
+
</para>
+
<para>
+
In <xref linkend="sec-configuration-syntax" />, we saw the following
+
structure of NixOS modules:
+
</para>
+
<programlisting language="bash">
+
{ config, pkgs, ... }:
+
+
{ option definitions
+
}
+
</programlisting>
+
<para>
+
This is actually an <emphasis>abbreviated</emphasis> form of module
+
that only defines options, but does not declare any. The structure
+
of full NixOS modules is shown in
+
<link linkend="ex-module-syntax">Example: Structure of NixOS
+
Modules</link>.
+
</para>
+
<anchor xml:id="ex-module-syntax" />
+
<para>
+
<emphasis role="strong">Example: Structure of NixOS
+
Modules</emphasis>
+
</para>
+
<programlisting language="bash">
+
{ config, pkgs, ... }:
+
+
{
+
imports =
+
[ paths of other modules
+
];
+
+
options = {
+
option declarations
+
};
+
+
config = {
+
option definitions
+
};
+
}
+
</programlisting>
+
<para>
+
The meaning of each part is as follows.
+
</para>
+
<itemizedlist>
+
<listitem>
+
<para>
+
The first line makes the current Nix expression a function. The
+
variable <literal>pkgs</literal> contains Nixpkgs (by default,
+
it takes the <literal>nixpkgs</literal> entry of
+
<literal>NIX_PATH</literal>, see the
+
<link xlink:href="https://nixos.org/manual/nix/stable/#sec-common-env">Nix
+
manual</link> for further details), while
+
<literal>config</literal> contains the full system
+
configuration. This line can be omitted if there is no reference
+
to <literal>pkgs</literal> and <literal>config</literal> inside
+
the module.
+
</para>
+
</listitem>
+
<listitem>
+
<para>
+
This <literal>imports</literal> list enumerates the paths to
+
other NixOS modules that should be included in the evaluation of
+
the system configuration. A default set of modules is defined in
+
the file <literal>modules/module-list.nix</literal>. These don't
+
need to be added in the import list.
+
</para>
+
</listitem>
+
<listitem>
+
<para>
+
The attribute <literal>options</literal> is a nested set of
+
<emphasis>option declarations</emphasis> (described below).
+
</para>
+
</listitem>
+
<listitem>
+
<para>
+
The attribute <literal>config</literal> is a nested set of
+
<emphasis>option definitions</emphasis> (also described below).
+
</para>
+
</listitem>
+
</itemizedlist>
+
<para>
+
<link linkend="locate-example">Example: NixOS Module for the
+
<quote>locate</quote> Service</link> shows a module that handles the
+
regular update of the <quote>locate</quote> database, an index of
+
all files in the file system. This module declares two options that
+
can be defined by other modules (typically the user’s
+
<literal>configuration.nix</literal>):
+
<literal>services.locate.enable</literal> (whether the database
+
should be updated) and <literal>services.locate.interval</literal>
+
(when the update should be done). It implements its functionality by
+
defining two options declared by other modules:
+
<literal>systemd.services</literal> (the set of all systemd
+
services) and <literal>systemd.timers</literal> (the list of
+
commands to be executed periodically by <literal>systemd</literal>).
+
</para>
+
<anchor xml:id="locate-example" />
+
<para>
+
<emphasis role="strong">Example: NixOS Module for the
+
<quote>locate</quote> Service</emphasis>
+
</para>
+
<programlisting language="bash">
+
{ config, lib, pkgs, ... }:
+
+
with lib;
+
+
let
+
cfg = config.services.locate;
+
in {
+
options.services.locate = {
+
enable = mkOption {
+
type = types.bool;
+
default = false;
+
description = ''
+
If enabled, NixOS will periodically update the database of
+
files used by the locate command.
+
'';
+
};
+
+
interval = mkOption {
+
type = types.str;
+
default = &quot;02:15&quot;;
+
example = &quot;hourly&quot;;
+
description = ''
+
Update the locate database at this interval. Updates by
+
default at 2:15 AM every day.
+
+
The format is described in
+
systemd.time(7).
+
'';
+
};
+
+
# Other options omitted for documentation
+
};
+
+
config = {
+
systemd.services.update-locatedb =
+
{ description = &quot;Update Locate Database&quot;;
+
path = [ pkgs.su ];
+
script =
+
''
+
mkdir -m 0755 -p $(dirname ${toString cfg.output})
+
exec updatedb \
+
--localuser=${cfg.localuser} \
+
${optionalString (!cfg.includeStore) &quot;--prunepaths='/nix/store'&quot;} \
+
--output=${toString cfg.output} ${concatStringsSep &quot; &quot; cfg.extraFlags}
+
'';
+
};
+
+
systemd.timers.update-locatedb = mkIf cfg.enable
+
{ description = &quot;Update timer for locate database&quot;;
+
partOf = [ &quot;update-locatedb.service&quot; ];
+
wantedBy = [ &quot;timers.target&quot; ];
+
timerConfig.OnCalendar = cfg.interval;
+
};
+
};
+
}
+
</programlisting>
+
<xi:include href="option-declarations.section.xml" />
+
<xi:include href="option-types.section.xml" />
+
<xi:include href="option-def.section.xml" />
+
<xi:include href="assertions.section.xml" />
+
<xi:include href="meta-attributes.section.xml" />
+
<xi:include href="importing-modules.section.xml" />
+
<xi:include href="replace-modules.section.xml" />
+
<xi:include href="freeform-modules.section.xml" />
+
<xi:include href="settings-options.section.xml" />
+
</chapter>