Remote build

Как сделать распределенные билды (реф https://nixos.wiki/wiki/Distributed_build и https://nixos.org/manual/nix/stable/advanced-topics/distributed-builds.html):

На машине-билдере (назову её wsl, в моем случае - это весло с арчем): Ставим сам nix:

1
2
yay -S nix
sudo useradd nix-builder -m -G nix-users

На локальной тачке (честная полноценная nixos, так её и назовем: nixos): Делаем ключ под коннект

1
sudo ssh-keygen -f /root/.ssh/nix_bulder_wsl -t ed25519

Там же, собираем конфиг /root/.ssh/config (кладем в рута, потому что демон на ремоут будет ходить от рута. Можно как-то более nix-way, но я сделал тупо cat):

1
2
3
4
5
6
7
Host builder
    HostName ${REMOTE_IP} # remote builder (wsl) hostname
    Port 22 # remote builder (wsl) ssh port
    User nix-builder # remote username

    IdentitiesOnly yes # strict only to one specified key
    IdentityFile /root/.ssh/nix_bulder_wsl # specify key

Мне ещё надо было вытянуть наружу из весла порт ssh, поэтому клоню https://github.com/mqudsi/tcpproxy и запускаю на хосте весла: cargo run -- 127.0.0.1:22 -b ${REMOTE_IP} -l 1022

На локальной машине [nixos]:

sudo ssh builder - сначала проставим ключ в known_hosts и проверим, что всё работает:

nix store ping --store ssh://builder --extra-experimental-features nix-command && echo ok

Также добавляем в конфиг никса на локалке:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
    nix.extraOptions = "builders-use-substitutes = true" # optional, useful when the builder has a faster internet connection than yours # понятия не имею, нахера надо и как работает

    nix.distributedBuilds = true; # собственно, включаем распределенные билды

    nix.buildMachines = [{
          hostName = "builder"; # хостнейм тачки, как в .ssh/config
          system = "x86_64-linux"; # система на тачке.
          protocol = "ssh"; # В гайде было ssh-ng, у меня не завелось
          maxJobs = 0; # -jN - короче, сколько одновременно тасок будет компиляться
          speedFactor = 2; # если много тачек, упростит выбор между ними. Просто абстрактная цифра.
          supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ]; # фичи, доступные на тачке. Некоторые пакеты могут не собраться, если не прописать
          mandatoryFeatures = [ ];
    }];
}

А дальше у меня не заработало, потому что nix-демон на ремоут тачке ругался на то, что, мол, архивы, которые я загрузил - плохие и подпись в них не проверяется. (ошибка because it lacks a signature by a trusted key)

Решил следующим способом (что-то из того, что я сделал - помогло.):

На [wsl] - генерим ключи для “подписи” кэша: nix-store --generate-binary-cache-key wsl cache-priv-key.pem cache-pub-key.pem

Добавляем ключ в конфиг: echo 'secret-key-files = /home/nix-builder/cache-priv-key.pem' >> '/etc/nix/nix.conf'

И добавляем локального для билдера пользователя в “доверенных пользователей”. Официальная дока не очень одобряет это, там тейк в том, что типа такой пользователь может сделать что угодно с системой, поэтому мол доверенные пользователи и он якобы эквивалентен руту.

echo 'trusted-users = nix-builder' >> '/etc/nix/nix.conf'

Подписываем уже имеющиеся пакеты: sudo nix store sign --all -k /home/nix-builder/cache-priv-key.pem --extra-experimental-features nix-command;

Не забываем рестартнуть демон: sudo systemctl restart nix-daemon.service

На локалке ещё добавляем в конфиг:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
    nix.settings = {
        trusted-public-keys = [
            "${cat cache-pub-key.pem on [wsl]}" # сюда пихаем содержимое файла cache-pub-key.pem с [wsl]
        ];
        substituters = [
            "ssh://builder"
        ];
    };
}

Готово, вы великолепны.