about summary refs log tree commit diff
path: root/modules/user/aszlig/programs/taalo-build/default.nix
blob: 6b50df1d6283755e841e8fb0f23af4060d945ec1 (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
{ config, pkgs, lib, ... }:

with lib;

{
  options.vuizvui.user.aszlig.programs.taalo-build = {
    enable = mkEnableOption "aszlig's build helper for remote builds";
  };
  config = mkIf config.vuizvui.user.aszlig.programs.taalo-build.enable {
    environment.systemPackages = singleton (pkgs.writeScriptBin "taalo-build" ''
      #!${pkgs.perl}/bin/perl -I${pkgs.nix}/lib/perl5/site_perl
      use strict;
      use Nix::CopyClosure;
      use Nix::SSH;
      use IPC::Open2;

      binmode STDERR, ":encoding(utf8)";

      open my $instantiate, "-|", "nix-instantiate", @ARGV
        or die "Failed to run nix-instantiate";
      my $to_realize = join "", <$instantiate>;
      close $instantiate or exit $? >> 8;

      chomp $to_realize;

      my ($from, $to);
      my $dest = 'nix-remote-build@taalo.headcounter.org';
      my $cmd = "exec ssh $dest -C -- nix-store --serve --write";
      my $pid = open2($from, $to, $cmd);

      # Do the handshake.
      my $magic;
      eval {
          my $SERVE_MAGIC_1 = 0x390c9deb; # FIXME
          my $clientVersion = 0x200;
          syswrite($to, pack("L<x4L<x4", $SERVE_MAGIC_1, $clientVersion))
            or die;
          $magic = readInt($from);
      };

      die "unable to connect to taalo\n" if $@;
      die "did not get valid handshake from taalo\n" if $magic != 0x5452eecb;

      my $serverVersion = readInt($from);
      die "unsupported server version\n"
        if $serverVersion < 0x200 || $serverVersion >= 0x300;

      Nix::CopyClosure::copyToOpen(
        $from, $to, "taalo", [$to_realize], 0, 0, 0, 1
      );

      writeInt(6, $to) or die;
      writeStrings([$to_realize], $to);
      writeInt(0, $to);
      writeInt(0, $to);

      my $res = readInt($from);

      close $to;

      waitpid($pid, 0);
      exit $res;
    '');
  };
}