lix/tests/remote-builds.nix
aszlig 6567ab95a0
build-remote: Fix missing log output
The storeUri variable in the build-remote hook is declared very much to
the start of the main function and a bunch of lines later, the same
variable gets checked via hasPrefix() but it gets assigned *after* that
check when the most suitable machine for the build was choosen.

So I guess this was just a typo in d16fd24973
and what we really want is to either checkd the prefix *after* assigning
storeUri or use bestMachine->storeUri directly.

I choose the latter, because the former could introduce even more
regressions if the try block where the variable gets assigned terminates
early.

Nevertheless, the reason why the log output didn't work is because
hasPrefix() checked for "ssh://" in front of storeUri, but if the
storeUri isn't set correctly (or at all), we don't get the log file
descriptor set up properly, leading to no log output.

I've adjusted the remote-builds test to include a regression test for
this, so that we can make sure we get a build output when using remote
builds.

In addition to that I've tested this with two of my build farms and the
build logs are emitted correctly again.

Signed-off-by: aszlig <aszlig@nix.build>
2017-11-25 01:34:18 +01:00

109 lines
3.4 KiB
Nix

# Test Nix's remote build feature.
{ system, nix }:
with import <nixpkgs/nixos/lib/testing.nix> { inherit system; };
makeTest (
let
# The configuration of the build slaves.
slave =
{ config, pkgs, ... }:
{ services.openssh.enable = true;
virtualisation.writableStore = true;
nix.package = nix;
nix.useSandbox = true;
};
# Trivial Nix expression to build remotely.
expr = config: nr: pkgs.writeText "expr.nix"
''
let utils = builtins.storePath ${config.system.build.extraUtils}; in
derivation {
name = "hello-${toString nr}";
system = "i686-linux";
PATH = "''${utils}/bin";
builder = "''${utils}/bin/sh";
args = [ "-c" "if [ ${toString nr} = 5 ]; then echo FAIL; exit 1; fi; echo Hello; mkdir $out $foo; cat /proc/sys/kernel/hostname > $out/host; ln -s $out $foo/bar; sleep 10" ];
outputs = [ "out" "foo" ];
}
'';
in
{
nodes =
{ slave1 = slave;
slave2 = slave;
client =
{ config, pkgs, ... }:
{ nix.maxJobs = 0; # force remote building
nix.distributedBuilds = true;
nix.buildMachines =
[ { hostName = "slave1";
sshUser = "root";
sshKey = "/root/.ssh/id_dsa";
system = "i686-linux";
maxJobs = 1;
}
{ hostName = "slave2";
sshUser = "root";
sshKey = "/root/.ssh/id_dsa";
system = "i686-linux";
maxJobs = 1;
}
];
virtualisation.writableStore = true;
virtualisation.pathsInNixDB = [ config.system.build.extraUtils ];
nix.package = nix;
nix.binaryCaches = [ ];
programs.ssh.extraConfig = "ConnectTimeout 30";
};
};
testScript = { nodes }:
''
startAll;
# Create an SSH key on the client.
my $key = `${pkgs.openssh}/bin/ssh-keygen -t dsa -f key -N ""`;
$client->succeed("mkdir -p -m 700 /root/.ssh");
$client->copyFileFromHost("key", "/root/.ssh/id_dsa");
$client->succeed("chmod 600 /root/.ssh/id_dsa");
# Install the SSH key on the slaves.
$client->waitForUnit("network.target");
foreach my $slave ($slave1, $slave2) {
$slave->succeed("mkdir -p -m 700 /root/.ssh");
$slave->copyFileFromHost("key.pub", "/root/.ssh/authorized_keys");
$slave->waitForUnit("sshd");
$client->succeed("ssh -o StrictHostKeyChecking=no " . $slave->name() . " 'echo hello world'");
}
# Perform a build and check that it was performed on the slave.
my $out = $client->succeed(
"nix-build ${expr nodes.client.config 1} 2> build-output",
"grep -q Hello build-output"
);
$slave1->succeed("test -e $out");
# And a parallel build.
my ($out1, $out2) = split /\s/,
$client->succeed('nix-store -r $(nix-instantiate ${expr nodes.client.config 2})\!out $(nix-instantiate ${expr nodes.client.config 3})\!out');
$slave1->succeed("test -e $out1 -o -e $out2");
$slave2->succeed("test -e $out1 -o -e $out2");
# And a failing build.
$client->fail("nix-build ${expr nodes.client.config 5}");
# Test whether the build hook automatically skips unavailable slaves.
$slave1->block;
$client->succeed("nix-build ${expr nodes.client.config 4}");
'';
})