Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help poor macOS users who can't build many closures on their host #560

Open
3noch opened this issue Dec 4, 2016 · 22 comments
Open

Help poor macOS users who can't build many closures on their host #560

3noch opened this issue Dec 4, 2016 · 22 comments

Comments

@3noch
Copy link

3noch commented Dec 4, 2016

Poor macOS users often run into issues when trying to deploy with nixops because many packages must be built on Linux. Perhaps we can offer them some help in the documentation and potentially point them to "workarounds" like this one: https://github.com/3noch/nix-vbox-build-slave

@copumpkin
Copy link
Member

@puffnfresh is working on something that could help a lot with this

@3noch
Copy link
Author

3noch commented Jul 23, 2017

@puffnfresh Do tell!

@copumpkin
Copy link
Member

copumpkin commented Jul 23, 2017

He packaged HyperKit (Docker's fork of xhyve) and is making a wrapper for it to act as a background remote builder for Nix, sort of the way Docker for Mac works, except with an even more minimal OS in it that only builds Nix derivations. So basically a similar idea to the VBox build worker but fully managed by Nix, free, and with no kernel components to install (or even privileged processes).

It's a work in progress but what I've seen so far has been very promising!

@domenkozar
Copy link
Member

I have merged all darwin related issues into this one. There is also an issue for "buildin fully remotely" at #260 and an unreviewed patch at #412

@proger
Copy link
Contributor

proger commented Sep 18, 2017

Is it still desirable to build on the virtual machine you're deploying to?
I had to stop using nix-daemon on Darwin to make it just work out of the box — I assume this has something to do with NixOS/nix#1061, if I'm testing on virtualbox I don't really want to run two VMs on a laptop.

@Gabriella439
Copy link
Contributor

@grahamc: In NixOS/nix#1061 (comment) you noted that you were able to get distributed builds working on a multi-user Nix installation on OS X. Is that documented anywhere?

@grahamc
Copy link
Member

grahamc commented Feb 8, 2018

I'm not sure I was able to get it working? Though, I'd definitely ping @LnL7 on that. I suspect nix-darwin helps out a lot here.

@Gabriella439
Copy link
Contributor

@grahamc: The reason I asked is that the way we got distributed builds working on multi-user Nix on OS X required running Nix commands as the root user (i.e. sudo). In other words, in addition to setting up NIX_BUILD_HOOK and NIX_REMOTE_SYSTEMS we also had to run sudo nix-build ... for distributed build support to kick in. However, having to run as root for distributed builds seems like the wrong way to do things.

@3noch
Copy link
Author

3noch commented Feb 8, 2018

Should have mentioned another workaround: https://github.com/LnL7/nix-docker/blob/master/start-docker-nix-build-slave

@dhess
Copy link
Contributor

dhess commented Feb 8, 2018

I am able tonix-build on macOS with remote builders. I am running multi-user Nix, plus nix-darwin to manage nix-daemon and its environment variables. In fact, thanks to @angerman’s trick to always set nixpkgs.system in configs (documented here: https://medium.com/@zw3rk/provisioning-a-nixos-server-from-macos-d36055afc4ad), I am now even able to run NixOS tests remotely from a Mac.

I haven’t had a chance to try this yet with NixOps, but @angerman’s post suggests that works as well.

@LnL7
Copy link
Member

LnL7 commented Feb 8, 2018

@Gabriel439 I wrote some basic instructions a couple days ago on how to configure the daemon without nix-darwin. The pitfall most people run into is known_hosts. https://gist.github.com/LnL7/ba2eac19e77cd6b4bb02c8de03bf5f4e

@LisannaAtHome
Copy link

LisannaAtHome commented Feb 22, 2018

I can build with nix-build on my x86_64-linux remote, but NixOps is not even trying to build remotely, even with nixpkgs.system = "x86_64-linux"; set in the deployment configuration. I'm using nix-darwin to manage my remote builder and nix-daemon.

This works:

$ nix-build -E 'with import  { system = "x86_64-linux"; }; hello.overrideAttrs (drv: { REBUILD = builtins.currentTime; })'

This does not work:

$ nixops deploy --build-only
building all machine configurations...
error: assertion failed at /nix/store/7i7x9g2f6rl50cxn2xpi0yy14l5x49z7-nixpkgs-18.03pre128804.127cea92389/nixpkgs/pkgs/os-specific/linux/kernel/generic.nix:48:1
(use ‘--show-trace’ to show detailed location information)
error: unable to build all machine configurations

UPDATE: adding "--option system x86_64-linux" to my nixops deploy command makes the remote building work.

@wmertens
Copy link
Contributor

@ledettwy Thanks, that option fixes evaluation. Everyone, this is the assertion that fails:

https://github.com/NixOS/nixpkgs/blob/56904d7c423f2b13b37fbd29f39bbb4b52bc7824/pkgs/os-specific/linux/kernel/generic.nix#L32

Should this assert stdenv.isLinux be there? If so, should the evaluation of this file be happening on the nixops host at all?

@Gabriella439
Copy link
Contributor

@ledettwy: Another way you can fix this problem without having to add --option system x86_64-linux to the command line is to add nixpkgs.system = "x86_64-linux" to the NixOS configuration of each machine that you deploy using NixOps. See:

https://nixos.org/nixos/options.html#nixpkgs.system

@wmertens: Yes, that assertion is correct and should not be changed. The root cause is that NixOps is trying to build a NixOS system whose nixpkgs.system option is set to something other than "x86_64-linux"

@LisannaAtHome
Copy link

LisannaAtHome commented Feb 27, 2018

@Gabriel439 I've read that, but that doesn't work for me. I have nixpkgs.system = "x86_64-linux" set in the configuration of the machine, but it still tries to build locally unless I set --option system x86_64-linux on the nixops command-line

@wmertens
Copy link
Contributor

wmertens commented Feb 27, 2018

I can confirm that setting nixpkgs.system = "x86_64-linux"; in the machine config makes it pass the evaluation. Haven't tried fully building yet.

@marsam
Copy link

marsam commented Apr 8, 2018

I think this might help https://github.com/puffnfresh/linuxkit-builder

@periklis
Copy link

periklis commented Jun 1, 2018

At our company we use the following instructions for our macOS users with multi-user installations. They are an amalgam of what works best with remote builds today on top of nix-docker:

Step 1: Install nix-docker

$ git clone http://github.com/lnl7/nix-docker
$ docker run --restart always --name nix-docker -d -p 3022:22 lnl7/nix:ssh

$ chmod 600 nix-docker/ssh/insecure_rsa
$ cp nix-docker/ssh/insecure_rsa /etc/nix/docker_rsa

Step 2: Add the following config inside your /var/root/.ssh/config and ~/.ssh/config

Host nix-docker
  User root
  HostName 127.0.0.1
  Port 3022
  IdentityFile /etc/nix/docker_rsa

Step 3: Add the nix-docker remote builder in your /etc/nix/machines file:

nix-docker x86_64-linux /etc/nix/docker_rsa 4 1

Step 4: Ensure that the machines file is used by Nix, by adding/ensuring the following in /etc/nix/nix.conf:

builders = @/etc/nix/machines

Step 5: Restart your nix daemon:

$ sudo launchctl unload /Library/LaunchDaemons/org.nixos.nix-daemon.plist
$ sudo launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist

Step 6: Check you local remote builder for x86_64-linux

$ nix-shell -p wget --builders ssh://nix-docker --option system x86_64-linux

$ nix build '(with import <nixpkgs> {}; runCommand "unameNixDocker" {} "uname -a > $out")' --builders ssh://nix-docker --option system x86_64-linux

$ cat ./result
Linux 1c33a493a33e 4.9.87-linuxkit-aufs #1 SMP Wed Mar 14 15:12:16 UTC 2018 x86_64 GNU/Linux

@werbitt
Copy link

werbitt commented Jun 11, 2018

Hi, I've been trying to get this working for a few days now, but I'm having some issues that I haven't been able to get passed. Here's what I've done so far

~> nix --version
nix (Nix) 2.0.4

~> nixops --version
NixOps 1.6.1pre2622_f10999a

~> ssh nix-docker --version
nix (Nix) 2.0
  1. Install Docker For Mac

  2. Run nix-docker

~> docker run --restart always --name nix-docker -d -p 3022:22 lnl7/nix:ssh
  1. Configure SSH

Get the insecure private key for nix-docker

~> sudo curl -fsSL https://raw.githubusercontent.com/LnL7/nix-docker/master/ssh/insecure_rsa -o /etc/nix/insecure_rsa
~> sudo chmod 600 /etc/nix/insecure_rsa

Add the following to ~/.ssh/config and /var/root/.ssh/config

Host nix-docker
  User root
  HostName 127.0.0.1
  Port 3022
  IdentityFile /etc/nix/insecure_rsa

Make sure known_hosts is updated for root

~> sudo ssh nix-docker
  1. Tell nix about the remote builder

Add the following to /etc/nix/machines

ssh://root@nix-docker x86_64-linux /etc/nix/insecure_rsa 1

Add the following to /etc/nix/nix.conf

builders = @/etc/nix/machines
  1. Test remote building
~> nix build \
  '(with import <nixpkgs> { system = "x86_64-linux"; }; runCommand "foo" {} "uname > $out")'
~> cat result
Linux
  1. Now here is where things aren't working as expected

Using the trivial example from https://nixos.org/nixops/manual/

trivial.nix

{
  network.description = "Web server";

  webserver =
    { config, pkgs, ... }:
    { services.httpd.enable = true;
      services.httpd.adminAddr = "[email protected]";
      services.httpd.documentRoot = "${pkgs.valgrind.doc}/share/doc/valgrind/html";
      networking.firewall.allowedTCPPorts = [ 80 ];
    };
}

trivial-vbox.nix

{
  webserver =
    { config, pkgs, ... }:
    { deployment.targetEnv = "virtualbox";
      
      # It doesn't matter if this is set or not
      nixpkgs.system = "x86_64-linux";

      deployment.virtualbox.memorySize = 1024; # megabytes
      deployment.virtualbox.vcpu = 2; # number of cpus
    };
}
  1. Create the nixops network
nixops create ./trivial.nix ./trivial-vbox.nix -d trivial
  1. Deploy without --option system "x86_64-linux"
~> nixops deploy -d trivial
building all machine configurations...
error: assertion failed at /nix/store/q5zi3ry7caaw5s7m501xsvy7lya3cixv-nixpkgs-18.09pre142355.41cdec2e513/nixpkgs/pkgs/os-specific/linux/kernel/generic.nix:48:1
(use '--show-trace' to show detailed location information)
error: unable to build all machine configurations
  1. Deploy with --option system "x86_64-linux"
~> nixops deploy -d trivial --option system "x86_64-linux"
building all machine configurations...
trace: warning: The option `system.stateVersion' defined in `/var/folders/91/hvqh9tt94wlb2h8lztfvvp2w0000gn/T/nixops-tmpHmLFor/physical.nix' has been renamed to `system.nixos.stateVersion'.
these derivations will be built:
  /nix/store/rb9blg08mn59lv2r710h1a025871zdg6-etc-ssh_known_hosts.drv
  /nix/store/4y24w1d0ln46yh0lvf3caanhrdi8rby1-etc.drv
  /nix/store/y7yi92a1bdw5fz7z1181dp8b9k490l0q-nixos-system-webserver-18.09pre142355.41cdec2e513.drv
  /nix/store/avnpka1sna8ny4qhwipcf5vkci3kfahv-nixops-machines.drv
building '/nix/store/rb9blg08mn59lv2r710h1a025871zdg6-etc-ssh_known_hosts.drv' on 'ssh://root@nix-docker'...
copying 1 paths...
copying path '/nix/store/yrdhv8dpc3sdl5w8z7fj4ngn71vfigpc-etc-ssh_known_hosts' from 'ssh://root@nix-docker'...
building '/nix/store/4y24w1d0ln46yh0lvf3caanhrdi8rby1-etc.drv' on 'ssh://root@nix-docker'...
copying 1 paths...
copying path '/nix/store/fn4vqlymiy18rcg96j67zjxx0gxpkgwa-etc' from 'ssh://root@nix-docker'...
building '/nix/store/y7yi92a1bdw5fz7z1181dp8b9k490l0q-nixos-system-webserver-18.09pre142355.41cdec2e513.drv' on 'ssh://root@nix-docker'...
copying 1 paths...
copying path '/nix/store/h99lvvba73za9rjla810fbrzxampgffd-nixos-system-webserver-18.09pre142355.41cdec2e513' from 'ssh://root@nix-docker'...
building '/nix/store/avnpka1sna8ny4qhwipcf5vkci3kfahv-nixops-machines.drv' on 'ssh://root@nix-docker'...
copying 1 paths...
copying path '/nix/store/6yhaybh6l279j0j0i99yq7nb2rdwnbrx-nixops-machines' from 'ssh://root@nix-docker'...
webserver> copying closure...
webserver> copying 476 paths...
webserver> copying path '/nix/store/0mmkix83i2g8vgn1ikmpvib1wylrihqf-acl-2.2.52-man' to 'ssh://[email protected]'...

... ellided copying paths

trivial> closures copied successfully
webserver> perl: warning: Setting locale failed.
webserver> perl: warning: Please check that your locale settings:
webserver> 	LANGUAGE = (unset),
webserver> 	LC_ALL = (unset),
webserver> 	LANG = "en_US.UTF-8"
webserver>     are supported and installed on your system.
webserver> perl: warning: Falling back to the standard locale ("C").
webserver> updating GRUB 2 menu...
webserver> Error getting name to temp file from template /boot/kernels/initrd-secrets.XXXXXXXX: Parent directory (/boot/kernels/) does not exist at /nix/store/rhaqrbjcx5mzd7zq2819x8bm83crwl35-install-grub.pl line 360.
webserver> error: Traceback (most recent call last):
  File "/nix/store/xqa1yns4962160wcsmr3l8zwf7bfiq97-nixops-1.6.1pre2622_f10999a/lib/python2.7/site-packages/nixops/deployment.py", line 731, in worker
    raise Exception("unable to activate new configuration (exit code {})".format(res))
Exception: unable to activate new configuration (exit code 1)

error: activation of 1 of 1 machines failed (namely on ‘webserver’)

I've tried to figure this out for a few days now without success. I also can't get 'Step 6' from Periklis's comment to work

~> nix-shell -p wget --builders ssh://nix-docker --option system x86_64-linux
/nix/store/xhcy0s61pg1bvmndbhscqn2jlzh5bvnn-bash-interactive-4.4-p19/bin/bash: /nix/store/xhcy0s61pg1bvmndbhscqn2jlzh5bvnn-bash-interactive-4.4-p19/bin/bash: cannot execute binary file

I'd appreceiate any thoughts, or if anyone can point me in the right direction.

@jezen
Copy link

jezen commented Jul 7, 2018

I'm having the same experience as @werbitt, and it's super frustrating.

I will have to downgrade again to Nix 1.11 so I can continue with my work.

@jezen
Copy link

jezen commented Jul 7, 2018

@werbitt Ok, I figured it out.

The option is no longer nixpkgs.system = "x86_64-linux";. You must now use nixpkgs.localSystem.system = "x86_64-linux";.

You should also not use --option system x86_64-linux.

@cmacrae
Copy link

cmacrae commented Jun 7, 2019

Hmm, can anyone see where I'm going wrong with this? 🤔 This is for remote builds on a physical aarch64-linux system.
I've added nixpkgs.localSystem.system = "aarch64-linux"; to the target host's config, but it seems I still need to pass --option system aarch64-linux to get it to use the remote builder (which does work).

Any help is greatly appreciated 🙏

Info dump
macOS host system

  • system: "x86_64-darwin"
  • host os: Darwin 18.6.0, macOS 10.14.5
  • multi-user?: yes
  • sandbox: no
  • version: nix-env (Nix) 2.2.2
  • channels(root): "darwin, nixpkgs-19.03pre172680.29200f05176"
  • channels(cmacrae): "darwin, nixpkgs-19.03pre172680.29200f05176"
  • nixpkgs: /nix/var/nix/profiles/per-user/root/channels/nixpkgs

macOS host builder config

    services.nix-daemon.enable = true;
    nix.distributedBuilds = true;
    nix.buildMachines = [
      {
        hostName = "net1";
        sshUser = "root";
        sshKey = "${homeDir}/.ssh/id_rsa";
        systems = [ "aarch64-linux" ];
        maxJobs = 2;
      }
    ];

Target host snippet

{ config, pkgs, lib, domain, ... }:
let
  localAddr = "10.0.0.2";
  gatewayAddr = "10.0.0.1";

in {
  deployment.hasFastConnection = true;
  deployment.targetHost = "net1.${domain}";
  nixpkgs.localSystem.system = "aarch64-linux";

...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests