diff options
Diffstat (limited to 'nixos/doc/manual/configuration/modularity.xml')
-rw-r--r-- | nixos/doc/manual/configuration/modularity.xml | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/nixos/doc/manual/configuration/modularity.xml b/nixos/doc/manual/configuration/modularity.xml new file mode 100644 index 00000000000..d95091bd162 --- /dev/null +++ b/nixos/doc/manual/configuration/modularity.xml @@ -0,0 +1,143 @@ +<section 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-modularity"> + +<title>Modularity</title> + +<para>The NixOS configuration mechanism is modular. If your +<filename>configuration.nix</filename> becomes too big, you can split +it into multiple files. Likewise, if you have multiple NixOS +configurations (e.g. for different computers) with some commonality, +you can move the common configuration into a shared file.</para> + +<para>Modules have exactly the same syntax as +<filename>configuration.nix</filename>. In fact, +<filename>configuration.nix</filename> is itself a module. You can +use other modules by including them from +<filename>configuration.nix</filename>, e.g.: + +<programlisting> +{ config, pkgs, ... }: + +{ imports = [ ./vpn.nix ./kde.nix ]; + services.httpd.enable = true; + environment.systemPackages = [ pkgs.emacs ]; + <replaceable>...</replaceable> +} +</programlisting> + +Here, we include two modules from the same directory, +<filename>vpn.nix</filename> and <filename>kde.nix</filename>. The +latter might look like this: + +<programlisting> +{ config, pkgs, ... }: + +{ services.xserver.enable = true; + services.xserver.displayManager.kdm.enable = true; + services.xserver.desktopManager.kde4.enable = true; + environment.systemPackages = [ pkgs.kde4.kscreensaver ]; +} +</programlisting> + +Note that both <filename>configuration.nix</filename> and +<filename>kde.nix</filename> define the option +<option>environment.systemPackages</option>. When multiple modules +define an option, NixOS will try to <emphasis>merge</emphasis> the +definitions. In the case of +<option>environment.systemPackages</option>, that’s easy: the lists of +packages can simply be concatenated. The value in +<filename>configuration.nix</filename> is merged last, so for +list-type options, it will appear at the end of the merged list. If +you want it to appear first, you can use <varname>mkBefore</varname>: + +<programlisting> +boot.kernelModules = mkBefore [ "kvm-intel" ]; +</programlisting> + +This causes the <literal>kvm-intel</literal> kernel module to be +loaded before any other kernel modules.</para> + +<para>For other types of options, a merge may not be possible. For +instance, if two modules define +<option>services.httpd.adminAddr</option>, +<command>nixos-rebuild</command> will give an error: + +<screen> +The unique option `services.httpd.adminAddr' is defined multiple times, in `/etc/nixos/httpd.nix' and `/etc/nixos/configuration.nix'. +</screen> + +When that happens, it’s possible to force one definition take +precedence over the others: + +<programlisting> +services.httpd.adminAddr = pkgs.lib.mkForce "bob@example.org"; +</programlisting> + +</para> + +<para>When using multiple modules, you may need to access +configuration values defined in other modules. This is what the +<varname>config</varname> function argument is for: it contains the +complete, merged system configuration. That is, +<varname>config</varname> is the result of combining the +configurations returned by every module<footnote><para>If you’re +wondering how it’s possible that the (indirect) +<emphasis>result</emphasis> of a function is passed as an +<emphasis>input</emphasis> to that same function: that’s because Nix +is a “lazy” language — it only computes values when they are needed. +This works as long as no individual configuration value depends on +itself.</para></footnote>. For example, here is a module that adds +some packages to <option>environment.systemPackages</option> only if +<option>services.xserver.enable</option> is set to +<literal>true</literal> somewhere else: + +<programlisting> +{ config, pkgs, ... }: + +{ environment.systemPackages = + if config.services.xserver.enable then + [ pkgs.firefox + pkgs.thunderbird + ] + else + [ ]; +} +</programlisting> + +</para> + +<para>With multiple modules, it may not be obvious what the final +value of a configuration option is. The command +<option>nixos-option</option> allows you to find out: + +<screen> +$ nixos-option services.xserver.enable +true + +$ nixos-option boot.kernelModules +[ "tun" "ipv6" "loop" <replaceable>...</replaceable> ] +</screen> + +Interactive exploration of the configuration is possible using +<command +xlink:href="https://github.com/edolstra/nix-repl">nix-repl</command>, +a read-eval-print loop for Nix expressions. It’s not installed by +default; run <literal>nix-env -i nix-repl</literal> to get it. A +typical use: + +<screen> +$ nix-repl '<nixos>' + +nix-repl> config.networking.hostName +"mandark" + +nix-repl> map (x: x.hostName) config.services.httpd.virtualHosts +[ "example.org" "example.gov" ] +</screen> + +</para> + +</section> |