diff options
Diffstat (limited to 'nixpkgs/nixos/doc/manual/development/writing-modules.xml')
-rw-r--r-- | nixpkgs/nixos/doc/manual/development/writing-modules.xml | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/nixpkgs/nixos/doc/manual/development/writing-modules.xml b/nixpkgs/nixos/doc/manual/development/writing-modules.xml new file mode 100644 index 000000000000..bbf793bb0be9 --- /dev/null +++ b/nixpkgs/nixos/doc/manual/development/writing-modules.xml @@ -0,0 +1,186 @@ +<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, 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="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" /> +</chapter> |