forked from lix-project/lix
140 lines
2.9 KiB
Perl
Executable file
140 lines
2.9 KiB
Perl
Executable file
#! /usr/bin/perl -w
|
|
|
|
use strict;
|
|
|
|
my $amWilling = shift @ARGV;
|
|
my $localSystem = shift @ARGV;
|
|
my $neededSystem = shift @ARGV;
|
|
my $storeExpr = shift @ARGV;
|
|
|
|
sub sendReply {
|
|
my $reply = shift;
|
|
open OUT, ">&3" or die;
|
|
print OUT "$reply\n";
|
|
close OUT;
|
|
}
|
|
|
|
# Decline if the local system can do the build.
|
|
if ($amWilling && ($localSystem eq $neededSystem)) {
|
|
sendReply "decline";
|
|
exit 0;
|
|
}
|
|
|
|
# Otherwise find a willing remote machine.
|
|
my %machines;
|
|
my %systemTypes;
|
|
my %sshKeys;
|
|
my %maxJobs;
|
|
my %curJobs;
|
|
|
|
# Read the list of machines.
|
|
open CONF, "< /home/eelco/nix/distributed/remote-systems.conf" or die;
|
|
|
|
while (<CONF>) {
|
|
chomp;
|
|
next if /^\s*$/;
|
|
/^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s*$/ or die;
|
|
$machines{$1} = "";
|
|
$systemTypes{$1} = $2;
|
|
$sshKeys{$1} = $3;
|
|
$maxJobs{$1} = $4;
|
|
}
|
|
|
|
close CONF;
|
|
|
|
# Read the current load status.
|
|
open LOAD, "< /home/eelco/nix/distributed/current-load" or die;
|
|
while (<LOAD>) {
|
|
chomp;
|
|
next if /^\s*$/;
|
|
/^\s*(\S+)\s+(\d+)\s*$/ or die;
|
|
$curJobs{$1} = $2;
|
|
}
|
|
close LOAD;
|
|
|
|
foreach my $cur (keys %machines) {
|
|
$curJobs{$cur} = 0 unless defined $curJobs{$cur};
|
|
}
|
|
|
|
# Find a suitable system.
|
|
my $rightType = 0;
|
|
my $machine;
|
|
foreach my $cur (keys %machines) {
|
|
if ($neededSystem eq $systemTypes{$cur}) {
|
|
$rightType = 1;
|
|
if ($curJobs{$cur} < $maxJobs{$cur})
|
|
{
|
|
$machine = $cur;
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!defined $machine) {
|
|
if ($rightType) {
|
|
sendReply "postpone";
|
|
exit 0;
|
|
} else {
|
|
sendReply "decline";
|
|
exit 0;
|
|
}
|
|
}
|
|
|
|
sendReply "accept";
|
|
open IN, "<&4" or die;
|
|
my $x = <IN>;
|
|
chomp $x;
|
|
print "got $x\n";
|
|
close IN;
|
|
|
|
print "BUILDING REMOTE: $storeExpr on $machine\n";
|
|
|
|
$curJobs{$machine} = $curJobs{$machine} + 1;
|
|
|
|
sub writeLoad {
|
|
open LOAD, "> /home/eelco/nix/distributed/current-load" or die;
|
|
foreach my $cur (keys %machines) {
|
|
print LOAD "$cur $curJobs{$cur}\n";
|
|
}
|
|
close LOAD;
|
|
}
|
|
|
|
writeLoad
|
|
|
|
|
|
my $ssh = "ssh -i $sshKeys{$machine} -x";
|
|
|
|
my $inputs = `cat inputs`;
|
|
$inputs =~ s/\n/ /g;
|
|
|
|
my $outputs = `cat outputs`;
|
|
$outputs =~ s/\n/ /g;
|
|
|
|
my $successors = `cat successors`;
|
|
$successors =~ s/\n/ /g;
|
|
|
|
system "rsync -a -e '$ssh' $storeExpr $inputs $machine:/nix/store";
|
|
die "cannot rsync inputs to $machine" if ($? != 0);
|
|
|
|
system "$ssh $machine /nix/bin/nix-store --validpath $storeExpr $inputs";
|
|
die "cannot set valid paths on $machine" if ($? != 0);
|
|
|
|
system "$ssh $machine /nix/bin/nix-store --successor $successors";
|
|
die "cannot set successors on $machine" if ($? != 0);
|
|
|
|
print "BUILDING...\n";
|
|
|
|
system "$ssh $machine /nix/bin/nix-store -qnfvvvv $storeExpr";
|
|
die "remote build on $machine failed" if ($? != 0);
|
|
|
|
print "REMOTE BUILD DONE\n";
|
|
|
|
foreach my $output (split '\n', $outputs) {
|
|
system "rsync -a -e '$ssh' $machine:$output /nix/store";
|
|
die "cannot rsync outputs from $machine" if ($? != 0);
|
|
}
|
|
|
|
$curJobs{$machine} = $curJobs{$machine} - 1;
|
|
|
|
writeLoad
|