at 23.05-pre 3.6 kB view raw
1<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-option-definitions"> 2 <title>Option Definitions</title> 3 <para> 4 Option definitions are generally straight-forward bindings of values 5 to option names, like 6 </para> 7 <programlisting language="bash"> 8config = { 9 services.httpd.enable = true; 10}; 11</programlisting> 12 <para> 13 However, sometimes you need to wrap an option definition or set of 14 option definitions in a <emphasis>property</emphasis> to achieve 15 certain effects: 16 </para> 17 <section xml:id="sec-option-definitions-delaying-conditionals"> 18 <title>Delaying Conditionals</title> 19 <para> 20 If a set of option definitions is conditional on the value of 21 another option, you may need to use <literal>mkIf</literal>. 22 Consider, for instance: 23 </para> 24 <programlisting language="bash"> 25config = if config.services.httpd.enable then { 26 environment.systemPackages = [ ... ]; 27 ... 28} else {}; 29</programlisting> 30 <para> 31 This definition will cause Nix to fail with an <quote>infinite 32 recursion</quote> error. Why? Because the value of 33 <literal>config.services.httpd.enable</literal> depends on the 34 value being constructed here. After all, you could also write the 35 clearly circular and contradictory: 36 </para> 37 <programlisting language="bash"> 38config = if config.services.httpd.enable then { 39 services.httpd.enable = false; 40} else { 41 services.httpd.enable = true; 42}; 43</programlisting> 44 <para> 45 The solution is to write: 46 </para> 47 <programlisting language="bash"> 48config = mkIf config.services.httpd.enable { 49 environment.systemPackages = [ ... ]; 50 ... 51}; 52</programlisting> 53 <para> 54 The special function <literal>mkIf</literal> causes the evaluation 55 of the conditional to be <quote>pushed down</quote> into the 56 individual definitions, as if you had written: 57 </para> 58 <programlisting language="bash"> 59config = { 60 environment.systemPackages = if config.services.httpd.enable then [ ... ] else []; 61 ... 62}; 63</programlisting> 64 </section> 65 <section xml:id="sec-option-definitions-setting-priorities"> 66 <title>Setting Priorities</title> 67 <para> 68 A module can override the definitions of an option in other 69 modules by setting a <emphasis>priority</emphasis>. All option 70 definitions that do not have the lowest priority value are 71 discarded. By default, option definitions have priority 1000. You 72 can specify an explicit priority by using 73 <literal>mkOverride</literal>, e.g. 74 </para> 75 <programlisting language="bash"> 76services.openssh.enable = mkOverride 10 false; 77</programlisting> 78 <para> 79 This definition causes all other definitions with priorities above 80 10 to be discarded. The function <literal>mkForce</literal> is 81 equal to <literal>mkOverride 50</literal>. 82 </para> 83 </section> 84 <section xml:id="sec-option-definitions-merging"> 85 <title>Merging Configurations</title> 86 <para> 87 In conjunction with <literal>mkIf</literal>, it is sometimes 88 useful for a module to return multiple sets of option definitions, 89 to be merged together as if they were declared in separate 90 modules. This can be done using <literal>mkMerge</literal>: 91 </para> 92 <programlisting language="bash"> 93config = mkMerge 94 [ # Unconditional stuff. 95 { environment.systemPackages = [ ... ]; 96 } 97 # Conditional stuff. 98 (mkIf config.services.bla.enable { 99 environment.systemPackages = [ ... ]; 100 }) 101 ]; 102</programlisting> 103 </section> 104</section>