Manual: Update chapter on remote builds

Alos add a command "nix ping-store" to make it easier to see if Nix
can connect to a remote builder (e.g. 'nix ping-store --store
ssh://mac').
This commit is contained in:
Eelco Dolstra 2018-02-21 16:22:49 +01:00
parent e2d71bd186
commit 0d54671b7b
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
3 changed files with 187 additions and 66 deletions

View file

@ -4,71 +4,109 @@
version="5.0" version="5.0"
xml:id='chap-distributed-builds'> xml:id='chap-distributed-builds'>
<title>Distributed Builds</title> <title>Remote Builds</title>
<para>Nix supports distributed builds, where a local Nix installation can <para>Nix supports remote builds, where a local Nix installation can
forward Nix builds to other machines over the network. This allows forward Nix builds to other machines. This allows multiple builds to
multiple builds to be performed in parallel (thus improving be performed in parallel and allows Nix to perform multi-platform
performance) and allows Nix to perform multi-platform builds in a builds in a semi-transparent way. For instance, if you perform a
semi-transparent way. For instance, if you perform a build for a build for a <literal>x86_64-darwin</literal> on an
<literal>x86_64-darwin</literal> on an <literal>i686-linux</literal> <literal>i686-linux</literal> machine, Nix can automatically forward
machine, Nix can automatically forward the build to a the build to a <literal>x86_64-darwin</literal> machine, if
<literal>x86_64-darwin</literal> machine, if available.</para> available.</para>
<para>You can enable distributed builds by setting the environment <para>To forward a build to a remote machine, its required that the
variable <envar>NIX_BUILD_HOOK</envar> to point to a program that Nix remote machine is accessible via SSH and that it has Nix
will call whenever it wants to build a derivation. The build hook installed. You can test whether connecting to the remote Nix instance
(typically a shell or Perl script) can decline the build, in which Nix works, e.g.
will perform it in the usual way if possible, or it can accept it, in
which case it is responsible for somehow getting the inputs of the
build to another machine, doing the build there, and getting the
results back.</para>
<example xml:id='ex-remote-systems'><title>Remote machine configuration: <screen>
<filename>remote-systems.conf</filename></title> $ nix ping-store --store ssh://mac
<programlisting> </screen>
nix@mcflurry.labs.cs.uu.nl x86_64-darwin /home/nix/.ssh/id_quarterpounder_auto 2
nix@scratchy.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 8 1 kvm
nix@itchy.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 8 2
nix@poochie.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 8 2 kvm perf
</programlisting>
</example>
<para>Nix ships with a build hook that should be suitable for most will try to connect to the machine named <literal>mac</literal>. It is
purposes. It uses <command>ssh</command> and possible to specify an SSH identity file as part of the remote store
<command>nix-copy-closure</command> to copy the build inputs and URI, e.g.
outputs and perform the remote build. To use it, you should set
<envar>NIX_BUILD_HOOK</envar> to <screen>
<filename><replaceable>prefix</replaceable>/libexec/nix/build-remote</filename>. $ nix ping-store --store ssh://mac?ssh-key=/home/alice/my-key
You should also define a list of available build machines and point </screen>
the environment variable <envar>NIX_REMOTE_SYSTEMS</envar> to
it. <envar>NIX_REMOTE_SYSTEMS</envar> must be an absolute path. An Since builds should be non-interactive, the key should not have a
example configuration is shown in <xref linkend='ex-remote-systems' passphrase. Alternatively, you can load identities ahead of time into
/>. Each line in the file specifies a machine, with the following <command>ssh-agent</command> or <command>gpg-agent</command>.</para>
bits of information:
<para>If you get the error
<screen>
bash: nix-store: command not found
error: cannot connect to 'mac'
</screen>
then you need to ensure that the <envar>PATH</envar> of
non-interactive login shells contains Nix.</para>
<warning><para>If you are building via the Nix daemon, it is the Nix
daemon user account (that is, <literal>root</literal>) that should
have SSH access to the remote machine. If you cant or dont want to
configure <literal>root</literal> to be able to access to remote
machine, you can use a private Nix store instead by passing
e.g. <literal>--store ~/my-nix</literal>.</para></warning>
<para>The list of remote machines can be specified on the command line
or in the Nix configuration file. The former is convenient for
testing. For example, the following command allows you to build a
derivation for <literal>x86_64-darwin</literal> on a Linux machine:
<screen>
$ uname
Linux
$ nix build \
'(with import &lt;nixpkgs> { system = "x86_64-darwin"; }; runCommand "foo" {} "uname > $out")' \
--builders 'ssh://mac x86_64-darwin'
[1/0/1 built, 0.0 MiB DL] building foo on ssh://mac
$ cat ./result
Darwin
</screen>
It is possible to specify multiple builders separated by a semicolon
or a newline, e.g.
<screen>
--builders 'ssh://mac x86_64-darwin ; ssh://beastie x86_64-freebsd'
</screen>
</para>
<para>Each machine specification consists of the following elements,
separated by spaces. Only the first element is required.
<orderedlist> <orderedlist>
<listitem><para>The name of the remote machine, with optionally the <listitem><para>The URI of the remote store in the format
user under which the remote build should be performed. This is <literal>ssh://[<replaceable>username</replaceable>@]<replaceable>hostname</replaceable></literal>,
actually passed as an argument to <command>ssh</command>, so it can e.g. <literal>ssh://nix@mac</literal> or
be an alias defined in your <literal>ssh://mac</literal>. For backward compatibility,
<literal>ssh://</literal> may be omitted. The hostname may be an
alias defined in your
<filename>~/.ssh/config</filename>.</para></listitem> <filename>~/.ssh/config</filename>.</para></listitem>
<listitem><para>A comma-separated list of Nix platform type <listitem><para>A comma-separated list of Nix platform type
identifiers, such as <literal>x86_64-darwin</literal>. It is identifiers, such as <literal>x86_64-darwin</literal>. It is
possible for a machine to support multiple platform types, e.g., possible for a machine to support multiple platform types, e.g.,
<literal>i686-linux,x86_64-linux</literal>.</para></listitem> <literal>i686-linux,x86_64-linux</literal>. If omitted, this
defaults to the local platform type.</para></listitem>
<listitem><para>The SSH private key to be used to log in to the <listitem><para>The SSH identity file to be used to log in to the
remote machine. Since builds should be non-interactive, this key remote machine. If omitted, SSH will use its regular
should not have a passphrase!</para></listitem> identities.</para></listitem>
<listitem><para>The maximum number of builds that <listitem><para>The maximum number of builds that Nix will execute
<filename>build-remote</filename> will execute in parallel on the in parallel on the machine. Typically this should be equal to the
machine. Typically this should be equal to the number of CPU cores. number of CPU cores. For instance, the machine
For instance, the machine <literal>itchy</literal> in the example <literal>itchy</literal> in the example will execute up to 8 builds
will execute up to 8 builds in parallel.</para></listitem> in parallel.</para></listitem>
<listitem><para>The “speed factor”, indicating the relative speed of <listitem><para>The “speed factor”, indicating the relative speed of
the machine. If there are multiple machines of the right type, Nix the machine. If there are multiple machines of the right type, Nix
@ -76,30 +114,69 @@ bits of information:
<listitem><para>A comma-separated list of <emphasis>supported <listitem><para>A comma-separated list of <emphasis>supported
features</emphasis>. If a derivation has the features</emphasis>. If a derivation has the
<varname>requiredSystemFeatures</varname> attribute, then <varname>requiredSystemFeatures</varname> attribute, then Nix will
<filename>build-remote</filename> will only perform the only perform the derivation on a machine that has the specified
derivation on a machine that has the specified features. For features. For instance, the attribute
instance, the attribute
<programlisting> <programlisting>
requiredSystemFeatures = [ "kvm" ]; requiredSystemFeatures = [ "kvm" ];
</programlisting> </programlisting>
will cause the build to be performed on a machine that has the will cause the build to be performed on a machine that has the
<literal>kvm</literal> feature (i.e., <literal>scratchy</literal> in <literal>kvm</literal> feature.</para></listitem>
the example above).</para></listitem>
<listitem><para>A comma-separated list of <emphasis>mandatory <listitem><para>A comma-separated list of <emphasis>mandatory
features</emphasis>. A machine will only be used to build a features</emphasis>. A machine will only be used to build a
derivation if all of the machines mandatory features appear in the derivation if all of the machines mandatory features appear in the
derivations <varname>requiredSystemFeatures</varname> attribute. derivations <varname>requiredSystemFeatures</varname>
Thus, in the example, the machine <literal>poochie</literal> will attribute..</para></listitem>
only do derivations that have
<varname>requiredSystemFeatures</varname> set to <literal>["kvm"
"perf"]</literal> or <literal>["perf"]</literal>.</para></listitem>
</orderedlist> </orderedlist>
</para> For example, the machine specification
<programlisting>
nix@scratchy.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 8 1 kvm
nix@itchy.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 8 2
nix@poochie.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 1 2 kvm benchmark
</programlisting>
specifies several machines that can perform
<literal>i686-linux</literal> builds. However,
<literal>poochie</literal> will only do builds that have the attribute
<programlisting>
requiredSystemFeatures = [ "benchmark" ];
</programlisting>
or
<programlisting>
requiredSystemFeatures = [ "benchmark" "kvm" ];
</programlisting>
<literal>itchy</literal> cannot do builds that require
<literal>kvm</literal>, but <literal>scratchy</literal> does support
such builds. For regular builds, <literal>itchy</literal> will be
preferred over <literal>scratchy</literal> because it has a higher
speed factor.</para>
<para>Remote builders can also be configured in
<filename>nix.conf</filename>, e.g.
<programlisting>
builders = ssh://mac x86_64-darwin ; ssh://beastie x86_64-freebsd
</programlisting>
Finally, remote builders can be configured in a separate configuration
file included in <option>builders</option> via the syntax
<literal>@<replaceable>file</replaceable></literal>. For example,
<programlisting>
builders = @/etc/nix/machines
</programlisting>
causes the list of machines in <filename>/etc/nix/machines</filename>
to be included. (This is the default.)</para>
</chapter> </chapter>

View file

@ -779,6 +779,15 @@ builtins.fetchurl {
</varlistentry> </varlistentry>
<varlistentry xml:id="conf-builders">
<term><literal>builders</literal></term>
<listitem>
<para>A list of machines on which to perform builds. <phrase
condition="manual">See <xref linkend="chap-distributed-builds"
/> for details.</phrase></para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</para> </para>

35
src/nix/ping-store.cc Normal file
View file

@ -0,0 +1,35 @@
#include "command.hh"
#include "shared.hh"
#include "store-api.hh"
using namespace nix;
struct CmdPingStore : StoreCommand
{
std::string name() override
{
return "ping-store";
}
std::string description() override
{
return "test whether a store can be opened";
}
Examples examples() override
{
return {
Example{
"To test whether connecting to a remote Nix store via SSH works:",
"nix ping-store --store ssh://mac1"
},
};
}
void run(ref<Store> store) override
{
store->connect();
}
};
static RegisterCommand r1(make_ref<CmdPingStore>());