diff options
Diffstat (limited to 'src/content/blog/2018/07/17/guix-nixos.adoc')
-rw-r--r-- | src/content/blog/2018/07/17/guix-nixos.adoc | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/src/content/blog/2018/07/17/guix-nixos.adoc b/src/content/blog/2018/07/17/guix-nixos.adoc new file mode 100644 index 0000000..6005f9f --- /dev/null +++ b/src/content/blog/2018/07/17/guix-nixos.adoc @@ -0,0 +1,196 @@ +--- +title: Running Guix on NixOS +date: 2018-07-17 +layout: post +lang: en +ref: running-guix-on-nixos +--- +I wanted to run +Guix on a NixOS machine. Even though the Guix manual explains how to do it +[step by step][0], I needed a few extra ones to make it work properly. + +[0]: https://www.gnu.org/software/guix/manual/en/html_node/Binary-Installation.html#Binary-Installation + +I couldn't just install GuixSD because my wireless network card +doesn't have any free drivers (yet). + +## Creating `guixbuilder` users + +Guix requires you to create non-root users that will be used to perform +the builds in the isolated environments. + +The [manual][1] already provides you with a ready to run (as root) command for +creating the build users: + +[1]: https://www.gnu.org/software/guix/manual/en/html_node/Build-Environment-Setup.html#Build-Environment-Setup + +```bash +groupadd --system guixbuild +for i in `seq -w 1 10`; +do + useradd -g guixbuild -G guixbuild \ + -d /var/empty -s `which nologin` \ + -c "Guix build user $i" --system \ + guixbuilder$i; +done +``` + +However, In my personal NixOS I have disabled [`users.mutableUsers`][2], which +means that even if I run the above command it means that they'll be removed once +I rebuild my OS: + +[2]: https://nixos.org/nixos/manual/index.html#sec-user-management + +```shell +$ sudo nixos-rebuild switch +(...) +removing user ‘guixbuilder7’ +removing user ‘guixbuilder3’ +removing user ‘guixbuilder10’ +removing user ‘guixbuilder1’ +removing user ‘guixbuilder6’ +removing user ‘guixbuilder9’ +removing user ‘guixbuilder4’ +removing user ‘guixbuilder2’ +removing user ‘guixbuilder8’ +removing user ‘guixbuilder5’ +(...) +``` + +Instead of enabling `users.mutableUsers` I could add the Guix users by +adding them to my system configuration: + +```nix +{ config, pkgs, ...}: + +{ + + # ... NixOS usual config ellided ... + + users = { + mutableUsers = false; + + extraUsers = + let + andrehUser = { + andreh = { + # my custom user config + }; + }; + buildUser = (i: + { + "guixbuilder${i}" = { # guixbuilder$i + group = "guixbuild"; # -g guixbuild + extraGroups = ["guixbuild"]; # -G guixbuild + home = "/var/empty"; # -d /var/empty + shell = pkgs.nologin; # -s `which nologin` + description = "Guix build user ${i}"; # -c "Guix buid user $i" + isSystemUser = true; # --system + }; + } + ); + in + # merge all users + pkgs.lib.fold (str: acc: acc // buildUser str) + andrehUser + # for i in `seq -w 1 10` + (map (pkgs.lib.fixedWidthNumber 2) (builtins.genList (n: n+1) 10)); + + extraGroups.guixbuild = { + name = "guixbuild"; + }; + }; +} +``` + +Here I used `fold` and the `//` operator to merge all of the +configuration sets into a single `extraUsers` value. + +## Creating the `systemd` service + +One other thing missing was the `systemd` service. + +First I couldn't just copy the `.service` file to `/etc` since in NixOS +that folder isn't writable. But also I wanted the service to be better +integrated with the OS. + +That was a little easier than creating the users, all I had to do was translate +the provided [`guix-daemon.service.in`][3] configuration to an equivalent Nix +expression + +[3]: https://git.savannah.gnu.org/cgit/guix.git/tree/etc/guix-daemon.service.in?id=00c86a888488b16ce30634d3a3a9d871ed6734a2 + +```ini +# This is a "service unit file" for the systemd init system to launch +# 'guix-daemon'. Drop it in /etc/systemd/system or similar to have +# 'guix-daemon' automatically started. + +[Unit] +Description=Build daemon for GNU Guix + +[Service] +ExecStart=/var/guix/profiles/per-user/root/guix-profile/bin/guix-daemon --build-users-group=guixbuild +Environment=GUIX_LOCPATH=/root/.guix-profile/lib/locale +RemainAfterExit=yes +StandardOutput=syslog +StandardError=syslog + +# See <https://lists.gnu.org/archive/html/guix-devel/2016-04/msg00608.html>. +# Some package builds (for example, go@1.8.1) may require even more than +# 1024 tasks. +TasksMax=8192 + +[Install] +WantedBy=multi-user.target +``` + +This sample `systemd` configuration file became: + +```nix +guix-daemon = { + enable = true; + description = "Build daemon for GNU Guix"; + serviceConfig = { + ExecStart = "/var/guix/profiles/per-user/root/guix-profile/bin/guix-daemon --build-users-group=guixbuild"; + Environment="GUIX_LOCPATH=/root/.guix-profile/lib/locale"; + RemainAfterExit="yes"; + StandardOutput="syslog"; + StandardError="syslog"; + TaskMax= "8192"; + }; + wantedBy = [ "multi-user.target" ]; +}; +``` + +There you go! After running `sudo nixos-rebuild switch` I could get Guix +up and running: + +```bash +$ guix package -i hello +The following package will be installed: + hello 2.10 /gnu/store/bihfrh609gkxb9dp7n96wlpigiv3krfy-hello-2.10 + +substitute: updating substitutes from 'https://mirror.hydra.gnu.org'... 100.0% +The following derivations will be built: + /gnu/store/nznmdn6inpwxnlkrasydmda4s2vsp9hg-profile.drv + /gnu/store/vibqrvw4c8lacxjrkqyzqsdrmckv77kq-fonts-dir.drv + /gnu/store/hi8alg7wi0wgfdi3rn8cpp37zhx8ykf3-info-dir.drv + /gnu/store/cvkbp378cvfjikz7mjymhrimv7j12p0i-ca-certificate-bundle.drv + /gnu/store/d62fvxymnp95rzahhmhf456bsf0xg1c6-manual-database.drv +Creating manual page database... +1 entries processed in 0.0 s +2 packages in profile +$ hello +Hello, world! +``` + +Some improvements to this approach are: + +1. looking into [NixOS modules][4] and trying to bundle everything together + into a single logical unit; +2. [build Guix from source][5] and share the Nix store and daemon with Guix. + +Happy Guix/Nix hacking! + +[4]: https://nixos.org/nixos/manual/index.html#sec-writing-modules +[5]: https://www.gnu.org/software/guix/manual/en/html_node/Requirements.html#Requirements |