diff --git a/doc/manual/development.xml b/doc/manual/development.xml index f4d68526c5e..e79114d1785 100644 --- a/doc/manual/development.xml +++ b/doc/manual/development.xml @@ -7,6 +7,230 @@ NixOS. +
+ +Extending NixOS + +A unique syntax is used to express all system, hardware, computer and + service configurations. This syntax helps for reading and writing new + configuration files. It is coming with some extra strategies defined in + NixPkgs which are used to merge and evaluate all configuration files. + + A configuration file is the same as your own computer + configuration. + +Usual configuration file + +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption; + + options = { + services = { + locate = { + + enable = mkOption { + default = false; + example = true; + description = '' + If enabled, NixOS will periodically update the database of + files used by the locate command. + ''; + }; + + period = mkOption { + default = "15 02 * * *"; + description = '' + This option defines (in the format used by cron) when the + locate database is updated. + The default is to update at 02:15 (at night) every day. + ''; + }; + + }; + + }; + }; +in + +###### implementation +let + cfg = config.services.locate; + inherit (pkgs.lib) mkIf mkThenElse; + + locatedb = "/var/cache/locatedb"; + logfile = "/var/log/updatedb"; + cmd = "root updatedb --localuser=nobody --output=${locatedb} > ${logfile}"; +in + +mkIf cfg.enable { + require = [ + options + + # config.services.cron + (import ../../upstart-jobs/cron.nix) + ]; + + services = { + cron = { + systemCronJobs = mkThenElse { + thenPart = "${cfg.period} root ${cmd}"; + elsePart = ""; + }; + }; + }; +} + + + shows the configuration + file for the locate service which uses cron to update the + database at some dates which can be defined by the user. This nix + expression is coming + from upstart-jobs/cron/locate.nix. It shows a simple + example of a service that can be either distributed on many computer that + are using the same configuration or to shared with the community. This + file is divided in two with the interface and the implementation. Both + the interface and the implementation declare a configuration + set. + + + + + + This line declares the arguments of the configuration file. You + can omit this line if there is no reference to pkgs + and config inside the configuration file. + + The argument pkgs refers to NixPkgs and allow + you to access all attributes contained inside it. In this + example pkgs is used to retrieve common functions to + ease the writing of configuration files + like mkOption, mkIf + and mkThenElse. + + The argument config corresponds to the whole + NixOS configuration. This is a set which is build by merging all + configuration files imported to set up the system. Thus all options + declared are contained inside this variable. In this + example config is used to retrieve the status of + the enable flag. The important point of this + argument is that it contains either the result of the merge of different + settings or the default value, therefore you cannot assume + that is always false + because it may have been defined in another configuration file. + + + + + + This line is used to import a function that is useful for + writing this configuration file. + + + + + + The variable options is + a configuration set which is only used to declare + options with the function mkOption imported + from pkgs/lib/default.nix. Options may contained + any attribute but only the following have a special + meaning: default, example, + description, merge + and apply. + + The merge attribute is used to merge all values + defined in all configuration files and this function return a value + which has the same type as the default value. If the merge function is + not defined, then a default function + (pkgs.lib.mergeDefaultOption) is used to merge + values. The merge attribute is a function which + expect two arguments: the location of the option and the list of values + which have to be merged. + + The apply attribute is a function used to + process the option. Thus the value return + by would be + the result of the apply function called with either + the default value or the result of + the merge function. + + + + + + This line is a common trick used to reduce the amount of + writing. In this case cfg is just a sugar over + + + + + + + This line is used to declare a special IF + statement. If you had put a usual IF statement + here, with the same condition, then you will get an infinite loop. The + reason is that your condition ask for the value of the + option but in order to + get this value you have to evaluate all configuration sets including the + configuration set contained inside your file. + + To remove this extra complexity, mkIf has been + introduced to get rid of possible infinite loop and to factor your + writing. + + + + + + The attribute require is the only special + option that exists. It is used to embed all option declarations that + are required by your configuration file and it is also used to provide + the options that you are declaring. + + This attribute is processed + with pkgs.lib.uniqFlatten to collect all + configuration files that are used by your system and it avoid the + insertion of duplicated elements by comparing the configuration set codes. + + Currently, the file configuration.nix + implicitly embeds system/options.nix. If you need + a special configuration file, then you will have to add similar lines + to your computer configuration. + + + + + + As mkIf does not need + any then part or else part, + then you can specify one on each option definition with the + function mkThenElse. + + To avoid a lot of mkThenElse with empty + else part, a sugar has been added to infer the + corresponding empty-value of your option when the + function mkThenElse is not used. + + If your then part + and else part are identical, then you should use + the function mkAlways to ignore the condition. + + If you need to add another condition, then you can add mkIf to on + the appropriate location. Thus the then part will + only be used if all conditions declared with mkIf + are satisfied. + + + + + + + +
+
Building specific parts of NixOS