[Nix-dev] Using a remote machine for builds with two NixOS machines.
roconnor at theorem.ca
roconnor at theorem.ca
Wed Sep 30 21:31:58 CEST 2015
I have a slow laptop that needs a custom kernel. It usually takes
overnight to recompile a kernel, so to combat this, I've recently set up
my laptop to use my desktop to perform builds.
Since this process isn't so well documented, I though I would try to
make a record of what I did, or rather what I would do if I were doing
this again. I'll replace the contents of
https://nixos.org/wiki/Distributed_build with this, if there are no
complaints.
Step 1. Create and exchange signing keys.
To generate signing keys I vaguely follow the directions in
https://github.com/NixOS/nix/blob/master/doc/signing.txt
As root I run
# (umask 277 && `nix-build --no-out-link "<nixpkgs>" -A libressl`/bin/openssl genrsa -out /etc/nix/signing-key.sec 4096)
# `nix-build --no-out-link "<nixpkgs>" -A libressl`/bin/Aopenssl rsa -in /etc/nix/signing-key.sec -pubout > /etc/nix/signing-key.pub
This generates /etc/nix/signing-key.sec and /etc/nix/signing-key.pub.
This step can be done on either the client or server. The created files
should be copied to the other machine. Now both machines have copies of
both the private and public signing keys. These keys are used to share
closures between the two machines, via nix-copy-closure --sign, without
needing to necessarly use root accounts.
Step 2. Generate ssh keys
On the client (i.e. my laptop):
# ssh-keygen -t ed25519 -N "" -C nixBuild -f /root/.ssh/id_nixBuild -N ""
This will create both /root/.ssh/id_nixBuild and
/root/.ssh/id_nixBuild.pub files.
Step 3. Create a nixBuild account
On the server (i.e. my desktop), update /etc/nixos/configuration.nix to
add a new user
users.extraUsers.nixBuild = {
name = "nixBuild";
useDefaultShell = true;
openssh.authorizedKeys.keys = [ "ssh-ed25519 AAA... nixBuild" ];
};
replacing the string in the openssh.authorizedKeys.keys with the contents
of the /root/.ssh/id_nixBuild.pub file generated on the client machine.
The client will access the server via this account in order to run Nix
commands.
Step 4. Enable distributed builds.
On the client (i.e. my laptop), update /etc/nixos/configuration.nix to
enable distributed builds.
nix = {
distributedBuilds = true;
buildMachines = [{
hostName = "<insert your server machine's name here>";
maxJobs = <fill in maxJobs>;
sshKey = "/root/.ssh/id_nixBuild";
sshUser = "nixBuild";
system = "x86_64-linux";
}];
};
For the maxJobs field, run
$ nixos-option nix.maxJobs
on the server machine and use the "Value:" listed.
For the system field, run
$ nix-instantiate --eval -E 'builtins.currentSystem'
on both the client and server machines. They should both print the same
value, and you should use that value in the system field. You cannot use
a remote machine with a different system for remote builds.
And that is all. For testing purposes, you can set the nix.maxJobs value
in your client machines /etc/nixos/hardware-configuation.nix value
temporarily to 0. This will force all builds to be done remotely. You
can restore the value after you are done testing.
It goes without saying that after updating configuration.nix files, you
will need to run nixos-rebuild to realize the changes.
Some general comments: This setup means that both the client and server
trust each other's binaries. I'd prefer that only the client trust the
server's binaries, and have the client only upload source files to the
server to build; however I don't know how to force this.
Also it would be nice to restrict the nixBuild user on the server to only
run nix-commands.
--
Russell O'Connor <http://r6.ca/>
``All talk about `theft,''' the general counsel of the American Graphophone
Company wrote, ``is the merest claptrap, for there exists no property in
ideas musical, literary or artistic, except as defined by statute.''
More information about the nix-dev
mailing list