Manual: Expand the Development chapter
This commit is contained in:
parent
8d09a99a3a
commit
4d15ad22a2
@ -1012,7 +1012,7 @@ manpage or the Nix manual.</para>
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section><title>User management</title>
|
<section xml:id="sec-user-management"><title>User management</title>
|
||||||
|
|
||||||
<para>NixOS supports both declarative and imperative styles of user
|
<para>NixOS supports both declarative and imperative styles of user
|
||||||
management. In the declarative style, users are specified in
|
management. In the declarative style, users are specified in
|
||||||
|
@ -76,190 +76,132 @@ in <filename>nixos/</filename> as packages.</para>
|
|||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
|
||||||
<title>Extending NixOS</title>
|
<title>Writing NixOS modules</title>
|
||||||
|
|
||||||
<para>NixOS is based on a modular system for declarative configuration.
|
<para>NixOS has a modular system for declarative configuration. This
|
||||||
This system combines multiple <emphasis>modules</emphasis> to produce one
|
system combines multiple <emphasis>modules</emphasis> to produce the
|
||||||
configuration. One of the module which compose your computer
|
full system configuration. One of the modules that constitute the
|
||||||
configuration is <filename>/etc/nixos/configuration.nix</filename>. Other
|
configuration is <filename>/etc/nixos/configuration.nix</filename>.
|
||||||
modules are available under NixOS <filename>modules</filename>
|
Most of the others live in the <link
|
||||||
directory</para>
|
xlink:href="https://github.com/NixOS/nixpkgs/tree/master/nixos/modules"><filename>nixos/modules</filename></link>
|
||||||
|
subdirectory of the Nixpkgs tree.</para>
|
||||||
|
|
||||||
<para>A module is a file which handles one specific part of the
|
<para>Each NixOS module is a file that handles one logical aspect of
|
||||||
configuration. This part of the configuration could correspond to
|
the configuration, such as a specific kind of hardware, a service, or
|
||||||
hardware, a service, network settings, or preferences. A module
|
network settings. A module configuration does not have to handle
|
||||||
configuration does not have to handle everything from scratch, it can base
|
everything from scratch; it can use the functionality provided by
|
||||||
its configuration on other configurations provided by other modules. Thus
|
other modules for its implementation. Thus a module can
|
||||||
a module can <emphasis>define</emphasis> options to setup its
|
<emphasis>declare</emphasis> options that can be used by other
|
||||||
configuration, and it can also <emphasis>declare</emphasis> options to be
|
modules, and conversely can <emphasis>define</emphasis> options
|
||||||
fed by other modules.</para>
|
provided by other modules in its own implementation. For example, the
|
||||||
|
module <link
|
||||||
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/pam.nix"><filename>pam.nix</filename></link>
|
||||||
|
declares the option <option>security.pam.services</option> that allows
|
||||||
|
other modules (e.g. <link
|
||||||
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/ssh/sshd.nix"><filename>sshd.nix</filename></link>)
|
||||||
|
to define PAM services; and it defines the option
|
||||||
|
<option>environment.etc</option> (declared by <link
|
||||||
|
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/etc/etc.nix"><filename>etc.nix</filename></link>)
|
||||||
|
to cause files to be created in
|
||||||
|
<filename>/etc/pam.d</filename>.</para>
|
||||||
|
|
||||||
<!-- module syntax -->
|
<para xml:id="para-module-syn">In <xref
|
||||||
|
linkend="sec-configuration-syntax"/>, we saw the following structure
|
||||||
|
of NixOS modules:
|
||||||
|
|
||||||
<para xml:id="para-module-syn">A module is a file which contains a Nix
|
<programlisting>
|
||||||
expression. This expression should be either an expression which gets
|
{ config, pkgs, ... }:
|
||||||
evaluated into an attribute set or a function which returns an attribute
|
|
||||||
set.</para>
|
|
||||||
|
|
||||||
<para>When the expression is a function, it should expect only one argument
|
{ <replaceable>option definitions</replaceable>
|
||||||
which is an attribute set containing an attribute
|
}
|
||||||
named <varname>config</varname> and another attribute
|
</programlisting>
|
||||||
named <varname>pkgs</varname>. The <varname>config</varname> attribute
|
|
||||||
contains the result of the merge of all modules. This attribute is
|
|
||||||
evaluated lazily, such as any Nix expression. For more details on how
|
|
||||||
options are merged, see the details in <xref linkend="para-opt-decl"/>.
|
|
||||||
The <varname>pkgs</varname> attribute
|
|
||||||
contains <emphasis>nixpkgs</emphasis> attribute set of packages. This
|
|
||||||
attribute is necessary for declaring options.</para>
|
|
||||||
|
|
||||||
<example xml:id='module-syntax'><title>Usual module content</title>
|
This is actually an <emphasis>abbreviated</emphasis> form of module
|
||||||
|
that only defines options, but does not declare any. The structure of
|
||||||
|
full NixOS modules is shown in <xref linkend='ex-module-syntax' />.</para>
|
||||||
|
|
||||||
|
<example xml:id='ex-module-syntax'><title>Structure of NixOS modules</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{ config, pkgs, ... }: <co xml:id='module-syntax-1' />
|
{ config, pkgs, ... }: <co xml:id='module-syntax-1' />
|
||||||
|
|
||||||
{
|
{
|
||||||
imports =
|
imports =
|
||||||
[ <co xml:id='module-syntax-2' />
|
[ <replaceable>paths of other modules</replaceable> <co xml:id='module-syntax-2' />
|
||||||
];
|
];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
<co xml:id='module-syntax-3' />
|
<replaceable>option declarations</replaceable> <co xml:id='module-syntax-3' />
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
<co xml:id='module-syntax-4' />
|
<replaceable>option definitions</replaceable> <co xml:id='module-syntax-4' />
|
||||||
};
|
};
|
||||||
}</programlisting>
|
}</programlisting>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
<para><xref linkend='module-syntax' /> Illustrates
|
<para>The meaning of each part is as follows.
|
||||||
a <emphasis>module</emphasis> skeleton.
|
|
||||||
|
|
||||||
<calloutlist>
|
<calloutlist>
|
||||||
<callout arearefs='module-syntax-1'>
|
<callout arearefs='module-syntax-1'>
|
||||||
<para>This line makes the current Nix expression a function. This
|
<para>This line makes the current Nix expression a function. The
|
||||||
line can be omitted if there is no reference to <varname>pkgs</varname>
|
variable <varname>pkgs</varname> contains Nixpkgs, while
|
||||||
and <varname>config</varname> inside the module.</para>
|
<varname>config</varname> contains the full system configuration.
|
||||||
|
This line can be omitted if there is no reference to
|
||||||
|
<varname>pkgs</varname> and <varname>config</varname> inside the
|
||||||
|
module.</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
|
||||||
<callout arearefs='module-syntax-2'>
|
<callout arearefs='module-syntax-2'>
|
||||||
<para>This list is used to enumerate path to other modules which are
|
<para>This list enumerates the paths to other NixOS modules that
|
||||||
declaring options used by the current module. In NixOS, default modules
|
should be included in the evaluation of the system configuration.
|
||||||
are listed in the file <filename>modules/module-list.nix</filename>.
|
A default set of modules is defined in the file
|
||||||
The default modules don't need to be added in the import list.</para>
|
<filename>modules/module-list.nix</filename>. These don't need to
|
||||||
|
be added in the import list.</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
|
||||||
<callout arearefs='module-syntax-3'>
|
<callout arearefs='module-syntax-3'>
|
||||||
<para>This attribute set contains an attribute set of <emphasis>option
|
<para>The attribute <varname>options</varname> is a nested set of
|
||||||
declaration</emphasis>.</para>
|
<emphasis>option declarations</emphasis> (described below).</para>
|
||||||
</callout>
|
</callout>
|
||||||
|
|
||||||
<callout arearefs='module-syntax-4'>
|
<callout arearefs='module-syntax-4'>
|
||||||
<para>This attribute set contains an attribute set of <emphasis>option
|
<para>The attribute <varname>config</varname> is a nested set of
|
||||||
definitions</emphasis>. If the module does not have any imported
|
<emphasis>option definitions</emphasis> (also described
|
||||||
modules or any option declarations, then this attribute set can be used
|
below).</para>
|
||||||
in place of its parent attribute set. This is a common case for simple
|
|
||||||
modules such
|
|
||||||
as <filename>/etc/nixos/configuration.nix</filename>.</para>
|
|
||||||
</callout>
|
</callout>
|
||||||
</calloutlist>
|
</calloutlist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<!-- option definitions -->
|
<para><xref linkend='locate-example' /> shows a module that handles
|
||||||
|
the regular update of the “locate” database, an index of all files in
|
||||||
|
the file system. This module declares two options that can be defined
|
||||||
|
by other modules (typically the user’s
|
||||||
|
<filename>configuration.nix</filename>):
|
||||||
|
<option>services.locate.enable</option> (whether the database should
|
||||||
|
be updated) and <option>services.locate.period</option> (when the
|
||||||
|
update should be done). It implements its functionality by defining
|
||||||
|
two options declared by other modules:
|
||||||
|
<option>systemd.services</option> (the set of all systemd services)
|
||||||
|
and <option>services.cron.systemCronJobs</option> (the list of
|
||||||
|
commands to be executed periodically by <command>cron</command>).</para>
|
||||||
|
|
||||||
<para xml:id="para-opt-def">A module defines a configuration which would be
|
<example xml:id='locate-example'><title>NixOS module for the “locate” service</title>
|
||||||
interpreted by other modules. To define a configuration, a module needs
|
|
||||||
to provide option definitions. An option definition is a simple
|
|
||||||
attribute assignment.</para>
|
|
||||||
|
|
||||||
<para>Option definitions are made in a declarative manner. Without
|
|
||||||
properties, options will always be defined with the same value. To
|
|
||||||
introduce more flexibility in the system, option definitions are guarded
|
|
||||||
by <emphasis>properties</emphasis>.</para>
|
|
||||||
|
|
||||||
<para>Properties are means to introduce conditional values inside option
|
|
||||||
definitions. This conditional values can be distinguished in two
|
|
||||||
categories. The condition which are local to the current configuration
|
|
||||||
and conditions which are dependent on others configurations. Local
|
|
||||||
properties are <varname>mkIf</varname>
|
|
||||||
and <varname>mkAssert</varname>. Global properties
|
|
||||||
are <varname>mkOverride</varname>, <varname>mkDefault</varname>
|
|
||||||
and <varname>mkOrder</varname>.</para>
|
|
||||||
|
|
||||||
<para><varname>mkIf</varname> is used to remove the option definitions which
|
|
||||||
are below it if the condition is evaluated to
|
|
||||||
false. <varname>mkAssert</varname> expects the condition to be evaluated
|
|
||||||
to true otherwise it raises an error message.</para>
|
|
||||||
|
|
||||||
<para><varname>mkOverride</varname> is used to mask previous definitions if
|
|
||||||
the current value has a lower mask number. The mask value is 100 (default)
|
|
||||||
for any option definition which does not use this property.
|
|
||||||
Thus, <varname>mkDefault</varname> is just a short-cut with a higher mask
|
|
||||||
(1000) than the default mask value. This means that a module can set an
|
|
||||||
option definition as a preference, and still let another module defining
|
|
||||||
it with a different value without using any property.</para>
|
|
||||||
|
|
||||||
<para><varname>mkOrder</varname> is used to sort definitions based on the
|
|
||||||
rank number. The rank number will sort all options definitions before
|
|
||||||
giving the sorted list of option definition to the merge function defined
|
|
||||||
in the option declaration. A lower rank will move the definition to the
|
|
||||||
beginning and a higher rank will move the option toward the end. The
|
|
||||||
default rank is 100.</para>
|
|
||||||
|
|
||||||
<!-- option declarations -->
|
|
||||||
|
|
||||||
<para xml:id="para-opt-decl">A module may declare options which are used by
|
|
||||||
other module to change the configuration provided by the current module.
|
|
||||||
Changes to the option definitions are made with properties which are using
|
|
||||||
values extracted from the result of the merge of all modules
|
|
||||||
(the <varname>config</varname> argument).</para>
|
|
||||||
|
|
||||||
<para>The <varname>config</varname> argument reproduce the same hierarchy of
|
|
||||||
all options declared in all modules. For each option, the result of the
|
|
||||||
option is available, it is either the default value or the merge of all
|
|
||||||
definitions of the option.</para>
|
|
||||||
|
|
||||||
<para>Options are declared with the
|
|
||||||
function <varname>pkgs.lib.mkOption</varname>. This function expects an
|
|
||||||
attribute set which at least provides a description. A default value, an
|
|
||||||
example, a type, a merge function and a post-process function can be
|
|
||||||
added.</para>
|
|
||||||
|
|
||||||
<para>Types are used to provide a merge strategy for options and to ensure
|
|
||||||
the type of each option definitions. They are defined
|
|
||||||
in <varname>pkgs.lib.types</varname>.</para>
|
|
||||||
|
|
||||||
<para>The merge function expects a list of option definitions and merge
|
|
||||||
them to obtain one result of the same type.</para>
|
|
||||||
|
|
||||||
<para>The post-process function (named <varname>apply</varname>) takes the
|
|
||||||
result of the merge or of the default value, and produce an output which
|
|
||||||
could have a different type than the type expected by the option.</para>
|
|
||||||
|
|
||||||
<!-- end -->
|
|
||||||
|
|
||||||
<example xml:id='locate-example'><title>Locate Module Example</title>
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
with pkgs.lib;
|
with pkgs.lib;
|
||||||
|
|
||||||
let
|
let locatedb = "/var/cache/locatedb"; in
|
||||||
cfg = config.services.locate;
|
|
||||||
locatedb = "/var/cache/locatedb";
|
|
||||||
logfile = "/var/log/updatedb";
|
|
||||||
cmd =''root updatedb --localuser=nobody --output=${locatedb} > ${logfile}'';
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [ /path/to/nixpkgs/nixos/modules/services/scheduling/cron.nix ];
|
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
services.locate = {
|
services.locate = {
|
||||||
|
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
example = true;
|
|
||||||
type = with types; bool;
|
|
||||||
description = ''
|
description = ''
|
||||||
If enabled, NixOS will periodically update the database of
|
If enabled, NixOS will periodically update the database of
|
||||||
files used by the <command>locate</command> command.
|
files used by the <command>locate</command> command.
|
||||||
@ -267,35 +209,370 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
period = mkOption {
|
period = mkOption {
|
||||||
default = "15 02 * * *";
|
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
default = "15 02 * * *";
|
||||||
description = ''
|
description = ''
|
||||||
This option defines (in the format used by cron) when the
|
This option defines (in the format used by cron) when the
|
||||||
locate database is updated.
|
locate database is updated. The default is to update at
|
||||||
The default is to update at 02:15 (at night) every day.
|
02:15 at night every day.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
services.cron = {
|
|
||||||
enable = true;
|
|
||||||
systemCronJobs = "${cfg.period} root ${cmd}";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
|
||||||
|
systemd.services.update-locatedb =
|
||||||
|
{ description = "Update Locate Database";
|
||||||
|
path = [ pkgs.su ];
|
||||||
|
script =
|
||||||
|
''
|
||||||
|
mkdir -m 0755 -p $(dirname ${locatedb})
|
||||||
|
exec updatedb --localuser=nobody --output=${locatedb} --prunepaths='/tmp /var/tmp /media /run'
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services.cron.systemCronJobs = optional config.services.locate.enable
|
||||||
|
"${config.services.locate.period} root ${config.systemd.package}/bin/systemctl start update-locatedb.service";
|
||||||
|
|
||||||
};
|
};
|
||||||
}</programlisting>
|
}</programlisting>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
<para><xref linkend='locate-example' /> illustrates a module which handles
|
<section><title>Option declarations</title>
|
||||||
the regular update of the database which index all files on the file
|
|
||||||
system. This modules has option definitions to rely on the cron service
|
<para>An option declaration specifies the name, type and description
|
||||||
to run the command at predefined dates. In addition, this modules
|
of a NixOS configuration option. It is illegal to define an option
|
||||||
provides option declarations to enable the indexing and to use different
|
that hasn’t been declared in any module. A option declaration
|
||||||
period of time to run the indexing. Properties are used to prevent
|
generally looks like this:
|
||||||
ambiguous definitions of option (enable locate service and disable cron
|
|
||||||
services) and to ensure that no options would be defined if the locate
|
<programlisting>
|
||||||
service is not enabled.</para>
|
options = {
|
||||||
|
<replaceable>name</replaceable> = mkOption {
|
||||||
|
type = <replaceable>type specification</replaceable>;
|
||||||
|
default = <replaceable>default value</replaceable>;
|
||||||
|
example = <replaceable>example value</replaceable>;
|
||||||
|
description = "<replaceable>Description for use in the NixOS manual.</replaceable>";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>The function <varname>mkOption</varname> accepts the following arguments.
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>type</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>The type of the option (see below). It may be omitted,
|
||||||
|
but that’s not advisable since it may lead to errors that are
|
||||||
|
hard to diagnose.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>default</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>The default value used if no value is defined by any
|
||||||
|
module. A default is not required; in that case, if the option
|
||||||
|
value is ever used, an error will be thrown.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>example</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>An example value that will be shown in the NixOS manual.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>description</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>A textual description of the option, in DocBook format,
|
||||||
|
that will be included in the NixOS manual.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>Here is a non-exhaustive list of option types:
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>types.bool</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>A Boolean.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>types.int</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>An integer.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>types.str</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>A string.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>types.lines</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>A string. If there are multiple definitions, they are
|
||||||
|
concatenated, with newline characters in between.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>types.path</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>A path, defined as anything that, when coerced to a
|
||||||
|
string, starts with a slash. This includes derivations.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>types.listOf</varname> <replaceable>t</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>A list of elements of type <replaceable>t</replaceable>
|
||||||
|
(e.g., <literal>types.listOf types.str</literal> is a list of
|
||||||
|
strings). Multiple definitions are concatenated together.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>types.attrsOf</varname> <replaceable>t</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>A set of elements of type <replaceable>t</replaceable>
|
||||||
|
(e.g., <literal>types.attrsOf types.int</literal> is a set of
|
||||||
|
name/value pairs, the values being integers).</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>types.nullOr</varname> <replaceable>t</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Either the value <literal>null</literal> or something of
|
||||||
|
type <replaceable>t</replaceable>.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
You can also create new types using the function
|
||||||
|
<varname>mkOptionType</varname>. See
|
||||||
|
<filename>lib/types.nix</filename> in Nixpkgs for details.</para>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<section><title>Option definitions</title>
|
||||||
|
|
||||||
|
<para>Option definitions are generally straight-forward bindings of values to option names, like
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
config = {
|
||||||
|
services.httpd.enable = true;
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
However, sometimes you need to wrap an option definition or set of
|
||||||
|
option definitions in a <emphasis>property</emphasis> to achieve
|
||||||
|
certain effects:</para>
|
||||||
|
|
||||||
|
<simplesect><title>Delaying conditionals</title>
|
||||||
|
|
||||||
|
<para>If a set of option definitions is conditional on the value of
|
||||||
|
another option, you may need to use <varname>mkIf</varname>.
|
||||||
|
Consider, for instance:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
config = if config.services.httpd.enable then {
|
||||||
|
environment.systemPackages = [ <replaceable>...</replaceable> ];
|
||||||
|
<replaceable>...</replaceable>
|
||||||
|
} else {};
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
This definition will cause Nix to fail with an “infinite recursion”
|
||||||
|
error. Why? Because the value of
|
||||||
|
<option>config.services.httpd.enable</option> depends on the value
|
||||||
|
being constructed here. After all, you could also write the clearly
|
||||||
|
circular and contradictory:
|
||||||
|
<programlisting>
|
||||||
|
config = if config.services.httpd.enable then {
|
||||||
|
services.httpd.enable = false;
|
||||||
|
} else {
|
||||||
|
services.httpd.enable = true;
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
The solution is to write:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
config = mkIf config.services.httpd.enable {
|
||||||
|
environment.systemPackages = [ <replaceable>...</replaceable> ];
|
||||||
|
<replaceable>...</replaceable>
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
The special function <varname>mkIf</varname> causes the evaluation of
|
||||||
|
the conditional to be “pushed down” into the individual definitions,
|
||||||
|
as if you had written:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
config = {
|
||||||
|
environment.systemPackages = if config.services.httpd.enable then [ <replaceable>...</replaceable> ] else [];
|
||||||
|
<replaceable>...</replaceable>
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</simplesect>
|
||||||
|
|
||||||
|
<simplesect><title>Setting priorities</title>
|
||||||
|
|
||||||
|
<para>A module can override the definitions of an option in other
|
||||||
|
modules by setting a <emphasis>priority</emphasis>. All option
|
||||||
|
definitions that do not have the lowest priority value are discarded.
|
||||||
|
By default, option definitions have priority 1000. You can specify an
|
||||||
|
explicit priority by using <varname>mkOverride</varname>, e.g.
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
services.openssh.enable = mkOverride 10 false;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
This definition causes all other definitions with priorities above 10
|
||||||
|
to be discarded. The function <varname>mkForce</varname> is
|
||||||
|
equal to <varname>mkOverride 50</varname>.</para>
|
||||||
|
|
||||||
|
</simplesect>
|
||||||
|
|
||||||
|
<simplesect><title>Merging configurations</title>
|
||||||
|
|
||||||
|
<para>In conjunction with <literal>mkIf</literal>, it is sometimes
|
||||||
|
useful for a module to return multiple sets of option definitions, to
|
||||||
|
be merged together as if they were declared in separate modules. This
|
||||||
|
can be done using <varname>mkMerge</varname>:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
config = mkMerge
|
||||||
|
[ # Unconditional stuff.
|
||||||
|
{ environment.systemPackages = [ <replaceable>...</replaceable> ];
|
||||||
|
}
|
||||||
|
# Conditional stuff.
|
||||||
|
(mkIf config.services.bla.enable {
|
||||||
|
environment.systemPackages = [ <replaceable>...</replaceable> ];
|
||||||
|
})
|
||||||
|
];
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</simplesect>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<section><title>Important options</title>
|
||||||
|
|
||||||
|
<para>NixOS has many options, but some are of particular importance to
|
||||||
|
module writers.</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>etc.environment</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>This set defines files in <filename>/etc</filename>. A
|
||||||
|
typical use is:
|
||||||
|
<programlisting>
|
||||||
|
environment.etc."os-release".text =
|
||||||
|
''
|
||||||
|
NAME=NixOS
|
||||||
|
<replaceable>...</replaceable>
|
||||||
|
'';
|
||||||
|
</programlisting>
|
||||||
|
which causes a file named <filename>/etc/os-release</filename>
|
||||||
|
to be created with the given contents.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>system.activationScripts</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>A set of shell script fragments that must be executed
|
||||||
|
whenever the configuration is activated (i.e., at boot time, or
|
||||||
|
after running <command>nixos-rebuild switch</command>). For instance,
|
||||||
|
<programlisting>
|
||||||
|
system.activationScripts.media =
|
||||||
|
''
|
||||||
|
mkdir -m 0755 -p /media
|
||||||
|
'';
|
||||||
|
</programlisting>
|
||||||
|
causes the directory <filename>/media</filename> to be created.
|
||||||
|
Activation scripts must be idempotent. They should not start
|
||||||
|
background processes such as daemons; use
|
||||||
|
<option>systemd.services</option> for that.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>systemd.services</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>This is the set of systemd services. Example:
|
||||||
|
<programlisting>
|
||||||
|
systemd.services.dhcpcd =
|
||||||
|
{ description = "DHCP Client";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "systemd-udev-settle.service" ];
|
||||||
|
path = [ dhcpcd pkgs.nettools pkgs.openresolv ];
|
||||||
|
serviceConfig =
|
||||||
|
{ Type = "forking";
|
||||||
|
PIDFile = "/run/dhcpcd.pid";
|
||||||
|
ExecStart = "${dhcpcd}/sbin/dhcpcd --config ${dhcpcdConf}";
|
||||||
|
Restart = "always";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
which creates the systemd unit
|
||||||
|
<literal>dhcpcd.service</literal>. The option
|
||||||
|
<option>wantedBy</option> determined which other units pull this
|
||||||
|
one in; <literal>multi-user.target</literal> is the default
|
||||||
|
target of the system, so <literal>dhcpcd.service</literal> will
|
||||||
|
always be started. The option
|
||||||
|
<option>serviceConfig.ExecStart</option> provides the main
|
||||||
|
command for the service; it’s also possible to provide pre-start
|
||||||
|
actions, stop scripts, and so on.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>users.extraUsers</option></term>
|
||||||
|
<term><option>users.extraGroups</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>If your service requires special UIDs or GIDs, you can
|
||||||
|
define them with these options. See <xref
|
||||||
|
linkend="sec-user-management"/> for details.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@ -306,48 +583,77 @@ in
|
|||||||
|
|
||||||
<title>Building specific parts of NixOS</title>
|
<title>Building specific parts of NixOS</title>
|
||||||
|
|
||||||
<para>
|
<para>With the command <command>nix-build</command>, you can build
|
||||||
|
specific parts of your NixOS configuration. This is done as follows:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-build /path/to/nixpkgs/nixos -A <replaceable>attr</replaceable></screen>
|
$ cd <replaceable>/path/to/nixpkgs/nixos</replaceable>
|
||||||
|
$ nix-build -A config.<replaceable>option</replaceable></screen>
|
||||||
|
|
||||||
where <replaceable>attr</replaceable> is an attribute in
|
where <replaceable>option</replaceable> is a NixOS option with type
|
||||||
<filename>/path/to/nixpkgs/nixos/default.nix</filename>. Attributes of interest include:
|
“derivation” (i.e. something that can be built). Attributes of
|
||||||
|
interest include:
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>config</varname></term>
|
<term><varname>system.build.toplevel</varname></term>
|
||||||
<listitem><para>The computer configuration generated from
|
<listitem>
|
||||||
the <envar>NIXOS_CONFIG</envar> environment variable (default
|
<para>The top-level option that builds the entire NixOS system.
|
||||||
is <filename>/etc/nixos/configuration.nix</filename>) with the NixOS
|
Everything else in your configuration is indirectly pulled in by
|
||||||
default set of modules.</para></listitem>
|
this option. This is what <command>nixos-rebuild</command>
|
||||||
|
builds and what <filename>/run/current-system</filename> points
|
||||||
|
to afterwards.</para>
|
||||||
|
|
||||||
|
<para>A shortcut to build this is:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nix-build -A system</screen>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>system</varname></term>
|
<term><varname>system.build.manual.manual</varname></term>
|
||||||
<listitem><para>The derivation which build your computer system. It is
|
<listitem><para>The NixOS manual.</para></listitem>
|
||||||
built by the command <command>nixos-rebuild
|
|
||||||
build</command></para></listitem>
|
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>vm</varname></term>
|
<term><varname>system.build.etc</varname></term>
|
||||||
<listitem><para>The derivation which build your computer system inside a
|
<listitem><para>A tree of symlinks that form the static parts of
|
||||||
virtual machine. It is built by the command <command>nixos-rebuild
|
<filename>/etc</filename>.</para></listitem>
|
||||||
build-vm</command></para></listitem>
|
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>system.build.initialRamdisk</varname></term>
|
||||||
|
<term><varname>system.build.kernel</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>The initial ramdisk and kernel of the system. This allows
|
||||||
|
a quick way to test whether the kernel and the initial ramdisk
|
||||||
|
boot correctly, by using QEMU’s <option>-kernel</option> and
|
||||||
|
<option>-initrd</option> options:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ nix-build -A config.system.build.initialRamdisk -o initrd
|
||||||
|
$ nix-build -A config.system.build.kernel -o kernel
|
||||||
|
$ qemu-system-x86_64 -kernel ./kernel/bzImage -initrd ./initrd/initrd -hda /dev/null
|
||||||
|
</screen>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>system.build.nixos-rebuild</varname></term>
|
||||||
|
<term><varname>system.build.nixos-install</varname></term>
|
||||||
|
<term><varname>system.build.nixos-generate-config</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>These build the corresponding NixOS commands.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
<para>
|
|
||||||
Most parts of NixOS can be built through the <varname>config</varname>
|
|
||||||
attribute set. This attribute set allows you to have a view of the merged
|
|
||||||
option definitions and all its derivations. Important derivations are store
|
|
||||||
inside the option <option>system.build</option> and can be listed with the
|
|
||||||
command <command>nix-instantiate --xml --eval-only /path/to/nixpkgs/nixos -A
|
|
||||||
config.system.build</command>
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
@ -370,8 +676,7 @@ you have to set <envar>NIXOS_CONFIG</envar> before
|
|||||||
running <command>nix-build</command> to build the ISO.
|
running <command>nix-build</command> to build the ISO.
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ export NIXOS_CONFIG=/path/to/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix
|
$ nix-build -A config.system.build.isoImage -I nixos-config=modules/installer/cd-dvd/installation-cd-minimal.nix</screen>
|
||||||
$ nix-build /path/to/nixpkgs/nixos -A config.system.build.isoImage</screen>
|
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -386,23 +691,6 @@ $ mount -o loop -t iso9660 ./result/iso/cd.iso /mnt/iso</screen>
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<!--===============================================================-->
|
|
||||||
|
|
||||||
<section>
|
|
||||||
|
|
||||||
<title>Testing/building the NixOS Manual</title>
|
|
||||||
|
|
||||||
<para>A quick way to see if your documentation improvements
|
|
||||||
or option descriptions look good:
|
|
||||||
|
|
||||||
<screen>
|
|
||||||
$ nix-build -A config.system.build.manual</screen>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
@ -415,8 +703,7 @@ tedious, so here is a quick way to see if the installer works
|
|||||||
properly:
|
properly:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ export NIXOS_CONFIG=/path/to/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix
|
$ nix-build -A config.system.build.nixos-install
|
||||||
$ nix-build /path/to/nixpkgs/nixos -A config.system.build.nixos-install
|
|
||||||
$ dd if=/dev/zero of=diskimage seek=2G count=0 bs=1
|
$ dd if=/dev/zero of=diskimage seek=2G count=0 bs=1
|
||||||
$ yes | mke2fs -j diskimage
|
$ yes | mke2fs -j diskimage
|
||||||
$ mount -o loop diskimage /mnt
|
$ mount -o loop diskimage /mnt
|
||||||
@ -430,74 +717,47 @@ $ ./result/bin/nixos-install</screen>
|
|||||||
|
|
||||||
<!--===============================================================-->
|
<!--===============================================================-->
|
||||||
|
|
||||||
<section>
|
<section><title>Whole-system testing using virtual machines</title>
|
||||||
|
|
||||||
<title>Testing the <literal>initrd</literal></title>
|
<para>Complete NixOS GNU/Linux systems can be tested in virtual
|
||||||
|
machines (VMs). This makes it possible to test a system upgrade or
|
||||||
<para>A quick way to test whether the kernel and the initial ramdisk
|
|
||||||
boot correctly is to use QEMU’s <option>-kernel</option> and
|
|
||||||
<option>-initrd</option> options:
|
|
||||||
|
|
||||||
<screen>
|
|
||||||
$ nix-build /path/to/nixpkgs/nixos -A config.system.build.initialRamdisk -o initrd
|
|
||||||
$ nix-build /path/to/nixpkgs/nixos -A config.system.build.kernel -o kernel
|
|
||||||
$ qemu-system-x86_64 -kernel ./kernel/bzImage -initrd ./initrd/initrd -hda /dev/null
|
|
||||||
</screen>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
|
|
||||||
<title>Whole-system testing using virtual machines</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Complete NixOS GNU/Linux systems can be tested in virtual machines
|
|
||||||
(VMs). This makes it possible to test a system upgrade or
|
|
||||||
configuration change before rebooting into it, using the
|
configuration change before rebooting into it, using the
|
||||||
<command>nixos-rebuild build-vm</command> or
|
<command>nixos-rebuild build-vm</command> or <command>nixos-rebuild
|
||||||
<command>nixos-rebuild build-vm-with-bootloader</command> command.
|
build-vm-with-bootloader</command> command.</para>
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
<!-- The following is adapted from
|
<!-- The following is adapted from
|
||||||
http://wiki.nixos.org/wiki/NixOS_VM_tests, by Eelco Dolstra. -->
|
http://wiki.nixos.org/wiki/NixOS_VM_tests, by Eelco Dolstra. -->
|
||||||
|
<para>The <filename>tests/</filename> directory in the NixOS source
|
||||||
The <filename>tests/</filename> directory in the NixOS source tree
|
tree contains several <emphasis>whole-system unit tests</emphasis>.
|
||||||
contains several <emphasis>whole-system unit tests</emphasis>.
|
|
||||||
These tests can be run<footnote><para>NixOS tests can be run both from
|
These tests can be run<footnote><para>NixOS tests can be run both from
|
||||||
NixOS and from a non-NixOS GNU/Linux distribution, provided the
|
NixOS and from a non-NixOS GNU/Linux distribution, provided the Nix
|
||||||
Nix package manager is installed.</para></footnote> from the NixOS
|
package manager is installed.</para></footnote> from the NixOS source
|
||||||
source tree as follows:
|
tree as follows:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ nix-build tests/ -A nfs.test
|
$ nix-build tests/ -A nfs.test
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
This performs an automated test of the NFS client and server
|
This performs an automated test of the NFS client and server
|
||||||
functionality in the Linux kernel, including file locking
|
functionality in the Linux kernel, including file locking semantics
|
||||||
semantics (e.g., whether locks are maintained across server
|
(e.g., whether locks are maintained across server crashes). It will
|
||||||
crashes). It will first build or download all the dependencies of
|
first build or download all the dependencies of the test (e.g., all
|
||||||
the test (e.g., all packages needed to run a NixOS VM). The test
|
packages needed to run a NixOS VM). The test is defined in <link
|
||||||
is defined in <link
|
|
||||||
xlink:href="https://nixos.org/repos/nix/nixos/trunk/tests/nfs.nix">
|
xlink:href="https://nixos.org/repos/nix/nixos/trunk/tests/nfs.nix">
|
||||||
<filename>tests/nfs.nix</filename></link>. If the test succeeds,
|
<filename>tests/nfs.nix</filename></link>. If the test succeeds,
|
||||||
<command>nix-build</command> will place a symlink
|
<command>nix-build</command> will place a symlink
|
||||||
<filename>./result</filename> in the current directory pointing at
|
<filename>./result</filename> in the current directory pointing at the
|
||||||
the location in the Nix store of the test results (e.g.,
|
location in the Nix store of the test results (e.g., screenshots, test
|
||||||
screenshots, test reports, and so on). In particular, a
|
reports, and so on). In particular, a pretty-printed log of the test
|
||||||
pretty-printed log of the test is written to
|
is written to <filename>log.html</filename>, which can be viewed using
|
||||||
<filename>log.html</filename>, which can be viewed using a web
|
a web browser like this:
|
||||||
browser like this:
|
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ firefox result/log.html
|
$ firefox result/log.html
|
||||||
</screen>
|
</screen>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>It is also possible to run the test environment interactively,
|
||||||
It is also possible to run the test environment interactively,
|
|
||||||
allowing you to experiment with the VMs. For example:
|
allowing you to experiment with the VMs. For example:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
@ -505,15 +765,12 @@ $ nix-build tests/ -A nfs.driver
|
|||||||
$ ./result/bin/nixos-run-vms
|
$ ./result/bin/nixos-run-vms
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
The script <command>nixos-run-vms</command> starts the three
|
The script <command>nixos-run-vms</command> starts the three virtual
|
||||||
virtual machines defined in the NFS test using QEMU/KVM. The root
|
machines defined in the NFS test using QEMU/KVM. The root file system
|
||||||
file system of the VMs is created on the fly and kept across VM
|
of the VMs is created on the fly and kept across VM restarts in
|
||||||
restarts in
|
<filename>./</filename><varname>hostname</varname><filename>.qcow2</filename>.</para>
|
||||||
<filename>./</filename><varname>hostname</varname><filename>.qcow2</filename>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
<para>Finally, the test itself can be run interactively. This is
|
||||||
Finally, the test itself can be run interactively. This is
|
|
||||||
particularly useful when developing or debugging a test:
|
particularly useful when developing or debugging a test:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
@ -523,8 +780,7 @@ starting VDE switch for network 1
|
|||||||
>
|
>
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
Perl statements can now be typed in to start or manipulate the
|
Perl statements can now be typed in to start or manipulate the VMs:
|
||||||
VMs:
|
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
> startAll;
|
> startAll;
|
||||||
@ -537,36 +793,30 @@ starting VDE switch for network 1
|
|||||||
> $client2->succeed("flock -n -s /data/lock true");
|
> $client2->succeed("flock -n -s /data/lock true");
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
The function <command>testScript</command> executes the entire
|
The function <command>testScript</command> executes the entire test
|
||||||
test script and drops you back into the test driver command line
|
script and drops you back into the test driver command line upon its
|
||||||
upon its completion. This allows you to inspect the state of the
|
completion. This allows you to inspect the state of the VMs after the
|
||||||
VMs after the test (e.g. to debug the test script).
|
test (e.g. to debug the test script).</para>
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
<para>This and other tests are continuously run on <link
|
||||||
This and other tests are continuously run on <link
|
|
||||||
xlink:href="http://hydra.nixos.org/jobset/nixos/trunk">the Hydra
|
xlink:href="http://hydra.nixos.org/jobset/nixos/trunk">the Hydra
|
||||||
instance at <literal>nixos.org</literal></link>, which allows
|
instance at <literal>nixos.org</literal></link>, which allows
|
||||||
developers to be notified of any regressions introduced by a NixOS
|
developers to be notified of any regressions introduced by a NixOS or
|
||||||
or Nixpkgs change.
|
Nixpkgs change.</para>
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
<para>The actual Nix programming interface to VM testing is in NixOS,
|
||||||
The actual Nix programming interface to VM testing is in NixOS,
|
|
||||||
under <link
|
under <link
|
||||||
xlink:href="https://nixos.org/repos/nix/nixos/trunk/lib/testing.nix">
|
xlink:href="https://nixos.org/repos/nix/nixos/trunk/lib/testing.nix">
|
||||||
<filename>lib/testing.nix</filename></link>. This file defines a
|
<filename>lib/testing.nix</filename></link>. This file defines a
|
||||||
function which takes an attribute set containing a
|
function which takes an attribute set containing a
|
||||||
<literal>nixpkgs</literal> attribute (the path to a Nixpkgs
|
<literal>nixpkgs</literal> attribute (the path to a Nixpkgs checkout),
|
||||||
checkout), and a <literal>system</literal> attribute (the system
|
and a <literal>system</literal> attribute (the system type). It
|
||||||
type). It returns an attribute set containing several utility
|
returns an attribute set containing several utility functions, among
|
||||||
functions, among which the main entry point is
|
which the main entry point is <literal>makeTest</literal>.
|
||||||
<literal>makeTest</literal>.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>The <literal>makeTest</literal> function takes a function
|
||||||
The <literal>makeTest</literal> function takes a function similar to
|
similar to that found in <link
|
||||||
that found in <link
|
|
||||||
xlink:href="https://nixos.org/repos/nix/nixos/trunk/tests/nfs.nix">
|
xlink:href="https://nixos.org/repos/nix/nixos/trunk/tests/nfs.nix">
|
||||||
<filename>tests/nfs.nix</filename></link> (discussed above). It
|
<filename>tests/nfs.nix</filename></link> (discussed above). It
|
||||||
returns an attribute set containing (among others):
|
returns an attribute set containing (among others):
|
||||||
@ -575,9 +825,9 @@ starting VDE switch for network 1
|
|||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>test</varname></term>
|
<term><varname>test</varname></term>
|
||||||
<listitem><para>A derivation containing the test log as an HTML file,
|
<listitem><para>A derivation containing the test log as an HTML
|
||||||
as seen above, suitable for presentation in the Hydra continuous
|
file, as seen above, suitable for presentation in the Hydra
|
||||||
build system.</para></listitem>
|
continuous build system.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -594,8 +844,10 @@ starting VDE switch for network 1
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
@ -103,7 +103,7 @@ in
|
|||||||
];
|
];
|
||||||
|
|
||||||
system.build = {
|
system.build = {
|
||||||
inherit nixos-install nixos-generate-config nixos-option;
|
inherit nixos-install nixos-generate-config nixos-option nixos-rebuild;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -58,8 +58,7 @@ with pkgs.lib;
|
|||||||
# Generate /etc/os-release. See
|
# Generate /etc/os-release. See
|
||||||
# http://0pointer.de/public/systemd-man/os-release.html for the
|
# http://0pointer.de/public/systemd-man/os-release.html for the
|
||||||
# format.
|
# format.
|
||||||
environment.etc = singleton
|
environment.etc."os-release".text =
|
||||||
{ source = pkgs.writeText "os-release"
|
|
||||||
''
|
''
|
||||||
NAME=NixOS
|
NAME=NixOS
|
||||||
ID=nixos
|
ID=nixos
|
||||||
@ -68,8 +67,6 @@ with pkgs.lib;
|
|||||||
PRETTY_NAME="NixOS ${config.system.nixosVersion} (${config.system.nixosCodeName})"
|
PRETTY_NAME="NixOS ${config.system.nixosVersion} (${config.system.nixosCodeName})"
|
||||||
HOME_URL="http://nixos.org/"
|
HOME_URL="http://nixos.org/"
|
||||||
'';
|
'';
|
||||||
target = "os-release";
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user