2014-08-24 18:18:18 +01:00
|
|
|
|
<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">
|
2018-05-02 00:57:09 +01:00
|
|
|
|
<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
|
2014-08-24 18:18:18 +01:00
|
|
|
|
xlink:href="https://github.com/NixOS/nixpkgs/tree/master/nixos/modules"><filename>nixos/modules</filename></link>
|
2018-05-02 00:57:09 +01:00
|
|
|
|
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
|
2014-08-24 18:18:18 +01:00
|
|
|
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/pam.nix"><filename>pam.nix</filename></link>
|
2018-05-02 00:57:09 +01:00
|
|
|
|
declares the option <option>security.pam.services</option> that allows other
|
|
|
|
|
modules (e.g.
|
|
|
|
|
<link
|
2014-08-24 18:18:18 +01:00
|
|
|
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/ssh/sshd.nix"><filename>sshd.nix</filename></link>)
|
2018-05-02 00:57:09 +01:00
|
|
|
|
to define PAM services; and it defines the option
|
|
|
|
|
<option>environment.etc</option> (declared by
|
|
|
|
|
<link
|
2014-08-24 18:18:18 +01:00
|
|
|
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/etc/etc.nix"><filename>etc.nix</filename></link>)
|
2018-05-02 00:57:09 +01:00
|
|
|
|
to cause files to be created in <filename>/etc/pam.d</filename>.
|
|
|
|
|
</para>
|
|
|
|
|
<para xml:id="para-module-syn">
|
|
|
|
|
In <xref
|
2014-08-24 18:18:18 +01:00
|
|
|
|
linkend="sec-configuration-syntax"/>, we saw the following structure
|
2018-05-02 00:57:09 +01:00
|
|
|
|
of NixOS modules:
|
2014-08-24 18:18:18 +01:00
|
|
|
|
<programlisting>
|
|
|
|
|
{ config, pkgs, ... }:
|
|
|
|
|
|
|
|
|
|
{ <replaceable>option definitions</replaceable>
|
|
|
|
|
}
|
|
|
|
|
</programlisting>
|
2018-05-02 00:57:09 +01:00
|
|
|
|
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>
|
2014-08-24 18:18:18 +01:00
|
|
|
|
<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>
|
2018-05-02 00:57:09 +01:00
|
|
|
|
</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, 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>
|
2014-08-24 18:18:18 +01:00
|
|
|
|
<programlisting>
|
|
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
2016-01-23 20:44:30 +00:00
|
|
|
|
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.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2014-08-24 18:18:18 +01:00
|
|
|
|
|
2016-01-23 20:44:30 +00:00
|
|
|
|
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>.
|
|
|
|
|
'';
|
2014-08-24 18:18:18 +01:00
|
|
|
|
};
|
|
|
|
|
|
2016-01-23 20:44:30 +00:00
|
|
|
|
# Other options omitted for documentation
|
2014-08-24 18:18:18 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
config = {
|
|
|
|
|
systemd.services.update-locatedb =
|
|
|
|
|
{ description = "Update Locate Database";
|
|
|
|
|
path = [ pkgs.su ];
|
|
|
|
|
script =
|
|
|
|
|
''
|
2016-01-23 20:44:30 +00:00
|
|
|
|
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}
|
2014-08-24 18:18:18 +01:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2016-01-23 20:44:30 +00:00
|
|
|
|
systemd.timers.update-locatedb = mkIf cfg.enable
|
|
|
|
|
{ description = "Update timer for locate database";
|
|
|
|
|
partOf = [ "update-locatedb.service" ];
|
|
|
|
|
wantedBy = [ "timers.target" ];
|
|
|
|
|
timerConfig.OnCalendar = cfg.interval;
|
|
|
|
|
};
|
2014-08-24 18:18:18 +01:00
|
|
|
|
};
|
2016-01-23 20:44:30 +00:00
|
|
|
|
}
|
|
|
|
|
</programlisting>
|
2018-05-02 00:57:09 +01:00
|
|
|
|
</example>
|
|
|
|
|
<xi:include href="option-declarations.xml" />
|
|
|
|
|
<xi:include href="option-types.xml" />
|
|
|
|
|
<xi:include href="option-def.xml" />
|
|
|
|
|
<xi:include href="assertions.xml" />
|
|
|
|
|
<xi:include href="meta-attributes.xml" />
|
|
|
|
|
<xi:include href="importing-modules.xml" />
|
|
|
|
|
<xi:include href="replace-modules.xml" />
|
2015-07-13 17:08:11 +01:00
|
|
|
|
</chapter>
|