at v206 6.3 kB view raw
1<chapter xmlns="http://docbook.org/ns/docbook" 2 xmlns:xlink="http://www.w3.org/1999/xlink" 3 xmlns:xi="http://www.w3.org/2001/XInclude" 4 version="5.0" 5 xml:id="sec-writing-modules"> 6 7<title>Writing NixOS Modules</title> 8 9<para>NixOS has a modular system for declarative configuration. This 10system combines multiple <emphasis>modules</emphasis> to produce the 11full system configuration. One of the modules that constitute the 12configuration is <filename>/etc/nixos/configuration.nix</filename>. 13Most of the others live in the <link 14xlink:href="https://github.com/NixOS/nixpkgs/tree/master/nixos/modules"><filename>nixos/modules</filename></link> 15subdirectory of the Nixpkgs tree.</para> 16 17<para>Each NixOS module is a file that handles one logical aspect of 18the configuration, such as a specific kind of hardware, a service, or 19network settings. A module configuration does not have to handle 20everything from scratch; it can use the functionality provided by 21other modules for its implementation. Thus a module can 22<emphasis>declare</emphasis> options that can be used by other 23modules, and conversely can <emphasis>define</emphasis> options 24provided by other modules in its own implementation. For example, the 25module <link 26xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/pam.nix"><filename>pam.nix</filename></link> 27declares the option <option>security.pam.services</option> that allows 28other modules (e.g. <link 29xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/ssh/sshd.nix"><filename>sshd.nix</filename></link>) 30to define PAM services; and it defines the option 31<option>environment.etc</option> (declared by <link 32xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/etc/etc.nix"><filename>etc.nix</filename></link>) 33to cause files to be created in 34<filename>/etc/pam.d</filename>.</para> 35 36<para xml:id="para-module-syn">In <xref 37linkend="sec-configuration-syntax"/>, we saw the following structure 38of NixOS modules: 39 40<programlisting> 41{ config, pkgs, ... }: 42 43{ <replaceable>option definitions</replaceable> 44} 45</programlisting> 46 47This is actually an <emphasis>abbreviated</emphasis> form of module 48that only defines options, but does not declare any. The structure of 49full NixOS modules is shown in <xref linkend='ex-module-syntax' />.</para> 50 51<example xml:id='ex-module-syntax'><title>Structure of NixOS Modules</title> 52<programlisting> 53{ config, pkgs, ... }: <co xml:id='module-syntax-1' /> 54 55{ 56 imports = 57 [ <replaceable>paths of other modules</replaceable> <co xml:id='module-syntax-2' /> 58 ]; 59 60 options = { 61 <replaceable>option declarations</replaceable> <co xml:id='module-syntax-3' /> 62 }; 63 64 config = { 65 <replaceable>option definitions</replaceable> <co xml:id='module-syntax-4' /> 66 }; 67}</programlisting> 68</example> 69 70<para>The meaning of each part is as follows. 71 72<calloutlist> 73 <callout arearefs='module-syntax-1'> 74 <para>This line makes the current Nix expression a function. The 75 variable <varname>pkgs</varname> contains Nixpkgs, while 76 <varname>config</varname> contains the full system configuration. 77 This line can be omitted if there is no reference to 78 <varname>pkgs</varname> and <varname>config</varname> inside the 79 module.</para> 80 </callout> 81 82 <callout arearefs='module-syntax-2'> 83 <para>This list enumerates the paths to other NixOS modules that 84 should be included in the evaluation of the system configuration. 85 A default set of modules is defined in the file 86 <filename>modules/module-list.nix</filename>. These don't need to 87 be added in the import list.</para> 88 </callout> 89 90 <callout arearefs='module-syntax-3'> 91 <para>The attribute <varname>options</varname> is a nested set of 92 <emphasis>option declarations</emphasis> (described below).</para> 93 </callout> 94 95 <callout arearefs='module-syntax-4'> 96 <para>The attribute <varname>config</varname> is a nested set of 97 <emphasis>option definitions</emphasis> (also described 98 below).</para> 99 </callout> 100</calloutlist> 101 102</para> 103 104<para><xref linkend='locate-example' /> shows a module that handles 105the regular update of the “locate” database, an index of all files in 106the file system. This module declares two options that can be defined 107by other modules (typically the user’s 108<filename>configuration.nix</filename>): 109<option>services.locate.enable</option> (whether the database should 110be updated) and <option>services.locate.period</option> (when the 111update should be done). It implements its functionality by defining 112two options declared by other modules: 113<option>systemd.services</option> (the set of all systemd services) 114and <option>services.cron.systemCronJobs</option> (the list of 115commands to be executed periodically by <command>cron</command>).</para> 116 117<example xml:id='locate-example'><title>NixOS Module for the “locate” Service</title> 118<programlisting> 119{ config, lib, pkgs, ... }: 120 121with lib; 122 123let locatedb = "/var/cache/locatedb"; in 124 125{ 126 options = { 127 128 services.locate = { 129 130 enable = mkOption { 131 type = types.bool; 132 default = false; 133 description = '' 134 If enabled, NixOS will periodically update the database of 135 files used by the <command>locate</command> command. 136 ''; 137 }; 138 139 period = mkOption { 140 type = types.str; 141 default = "15 02 * * *"; 142 description = '' 143 This option defines (in the format used by cron) when the 144 locate database is updated. The default is to update at 145 02:15 at night every day. 146 ''; 147 }; 148 149 }; 150 151 }; 152 153 config = { 154 155 systemd.services.update-locatedb = 156 { description = "Update Locate Database"; 157 path = [ pkgs.su ]; 158 script = 159 '' 160 mkdir -m 0755 -p $(dirname ${locatedb}) 161 exec updatedb --localuser=nobody --output=${locatedb} --prunepaths='/tmp /var/tmp /run' 162 ''; 163 }; 164 165 services.cron.systemCronJobs = optional config.services.locate.enable 166 "${config.services.locate.period} root ${config.systemd.package}/bin/systemctl start update-locatedb.service"; 167 168 }; 169}</programlisting> 170</example> 171 172<xi:include href="option-declarations.xml" /> 173<xi:include href="option-def.xml" /> 174 175</chapter>