at 16.09-beta 4.7 kB view raw
1<section 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-modularity"> 6 7<title>Modularity</title> 8 9<para>The NixOS configuration mechanism is modular. If your 10<filename>configuration.nix</filename> becomes too big, you can split 11it into multiple files. Likewise, if you have multiple NixOS 12configurations (e.g. for different computers) with some commonality, 13you can move the common configuration into a shared file.</para> 14 15<para>Modules have exactly the same syntax as 16<filename>configuration.nix</filename>. In fact, 17<filename>configuration.nix</filename> is itself a module. You can 18use other modules by including them from 19<filename>configuration.nix</filename>, e.g.: 20 21<programlisting> 22{ config, pkgs, ... }: 23 24{ imports = [ ./vpn.nix ./kde.nix ]; 25 services.httpd.enable = true; 26 environment.systemPackages = [ pkgs.emacs ]; 27 <replaceable>...</replaceable> 28} 29</programlisting> 30 31Here, we include two modules from the same directory, 32<filename>vpn.nix</filename> and <filename>kde.nix</filename>. The 33latter might look like this: 34 35<programlisting> 36{ config, pkgs, ... }: 37 38{ services.xserver.enable = true; 39 services.xserver.displayManager.kdm.enable = true; 40 services.xserver.desktopManager.kde4.enable = true; 41 environment.systemPackages = [ pkgs.kde4.kscreensaver ]; 42} 43</programlisting> 44 45Note that both <filename>configuration.nix</filename> and 46<filename>kde.nix</filename> define the option 47<option>environment.systemPackages</option>. When multiple modules 48define an option, NixOS will try to <emphasis>merge</emphasis> the 49definitions. In the case of 50<option>environment.systemPackages</option>, that’s easy: the lists of 51packages can simply be concatenated. The value in 52<filename>configuration.nix</filename> is merged last, so for 53list-type options, it will appear at the end of the merged list. If 54you want it to appear first, you can use <varname>mkBefore</varname>: 55 56<programlisting> 57boot.kernelModules = mkBefore [ "kvm-intel" ]; 58</programlisting> 59 60This causes the <literal>kvm-intel</literal> kernel module to be 61loaded before any other kernel modules.</para> 62 63<para>For other types of options, a merge may not be possible. For 64instance, if two modules define 65<option>services.httpd.adminAddr</option>, 66<command>nixos-rebuild</command> will give an error: 67 68<screen> 69The unique option `services.httpd.adminAddr' is defined multiple times, in `/etc/nixos/httpd.nix' and `/etc/nixos/configuration.nix'. 70</screen> 71 72When that happens, it’s possible to force one definition take 73precedence over the others: 74 75<programlisting> 76services.httpd.adminAddr = pkgs.lib.mkForce "bob@example.org"; 77</programlisting> 78 79</para> 80 81<para>When using multiple modules, you may need to access 82configuration values defined in other modules. This is what the 83<varname>config</varname> function argument is for: it contains the 84complete, merged system configuration. That is, 85<varname>config</varname> is the result of combining the 86configurations returned by every module<footnote><para>If you’re 87wondering how it’s possible that the (indirect) 88<emphasis>result</emphasis> of a function is passed as an 89<emphasis>input</emphasis> to that same function: that’s because Nix 90is a “lazy” language — it only computes values when they are needed. 91This works as long as no individual configuration value depends on 92itself.</para></footnote>. For example, here is a module that adds 93some packages to <option>environment.systemPackages</option> only if 94<option>services.xserver.enable</option> is set to 95<literal>true</literal> somewhere else: 96 97<programlisting> 98{ config, pkgs, ... }: 99 100{ environment.systemPackages = 101 if config.services.xserver.enable then 102 [ pkgs.firefox 103 pkgs.thunderbird 104 ] 105 else 106 [ ]; 107} 108</programlisting> 109 110</para> 111 112<para>With multiple modules, it may not be obvious what the final 113value of a configuration option is. The command 114<option>nixos-option</option> allows you to find out: 115 116<screen> 117$ nixos-option services.xserver.enable 118true 119 120$ nixos-option boot.kernelModules 121[ "tun" "ipv6" "loop" <replaceable>...</replaceable> ] 122</screen> 123 124Interactive exploration of the configuration is possible using 125<command 126xlink:href="https://github.com/edolstra/nix-repl">nix-repl</command>, 127a read-eval-print loop for Nix expressions. It’s not installed by 128default; run <literal>nix-env -i nix-repl</literal> to get it. A 129typical use: 130 131<screen> 132$ nix-repl '&lt;nixos>' 133 134nix-repl> config.networking.hostName 135"mandark" 136 137nix-repl> map (x: x.hostName) config.services.httpd.virtualHosts 138[ "example.org" "example.gov" ] 139</screen> 140 141</para> 142 143</section>