about summary refs log tree commit diff
path: root/distributed/build-remote.pl
blob: f1a9b10f4d60429815d04fa47d778c3fca43d12f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#! /usr/bin/perl -w

use strict;

my $amWilling = shift @ARGV;
my $localSystem = shift @ARGV;
my $neededSystem = shift @ARGV;
my $storeExpr = shift @ARGV;

# Decline if the local system can do the build.
if ($amWilling && ($localSystem eq $neededSystem)) {
    print "decline\n";
    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;

sub sendReply {
    my $reply = shift;
    open OUT, ">&3" or die;
    print OUT "$reply\n";
    close OUT;
}

# Find a suitable system.
my $rightType = 0;
my $machine;
foreach my $cur (keys %machines) {
    if ($neededSystem eq $systemTypes{$cur}) {
        $rightType = 1;
        if (!defined $curJobs{$cur} or
            ($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";

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);
}