NixOS vs Guix System, premiers pas

Voir aussi : video youtube - video peertube - journal linuxfr

NixOS et Guix System sont des distributions Linux basées sur des gestionnaires de paquets utilisant une approche fonctionnelle (Nix et GNU Guix). Cette approche permet de gérer des environnements logiciels reproductibles et composables, ce qui est très pratique pour un développeur ou pour un administrateur système.

Cet article ne compare pas vraiment NixOS et Guix System mais présente, pour les deux solutions, comment installer le système, le configurer et l’utiliser pour développer. L’idée est plutôt d’aider un utilisateur de l’un à découvrir l’autre, et vice et versa.

Installer le système

NixOS

NixOS nécessite une installation manuelle (voir le manuel NixOS ou le tuto 45). Celle-ci n’est pas compliquée mais un peu fastidieuse. Il s’agit notamment de :

Guix System

Guix System propose un installeur semi-graphique très pratique (voir le manuel de référence GNU Guix). Ainsi l’installation se résume à :

Mettre à jour le système

Les deux solutions fonctionnent de façon très similaire :

NixOS

$ sudo nix-channel --update
$ sudo nixos-rebuild switch
{ config, pkgs, ... }: {

  imports = [ ./hardware-configuration.nix ];

  boot.loader.grub = {
    enable = true;
    device = "/dev/sda";
    version = 2;
  };  

  i18n.defaultLocale = "fr_FR.UTF-8";
  system.stateVersion = "20.09";
  time.timeZone = "Europe/Paris";

  console = {
    font = "Lat2-Terminus16";
    keyMap = "fr-bepo";
  };

  environment.systemPackages = with pkgs; [ vim ];

  networking = {
    hostName = "mynixos";
    useDHCP = false;
    interfaces.enp0s3.useDHCP = true;
  };

  services = {
    xserver = {
      enable = true;
      layout = "fr";
      displayManager.lightdm.enable = true;
      desktopManager.xfce.enable = true;
    };
  };

  users.users.toto = {
    isNormalUser = true;
    extraGroups = [ "wheel" ];
  };
}

Guix System

$ guix pull
$ sudo guix system reconfigure /etc/config.scm
(use-modules (gnu) (gnu packages vim) (gnu packages admin) (gnu packages certs))
(use-service-modules desktop networking ssh xorg)

(operating-system
  (locale "fr_FR.utf8")
  (timezone "Europe/Paris")
  (keyboard-layout (keyboard-layout "fr" "bepo"))
  (host-name "myguix")

  (users (cons* (user-account
                  (name "toto")
                  (comment "Toto")
                  (group "users")
                  (home-directory "/home/toto")
                  (supplementary-groups '("wheel" "netdev" "audio" "video")))
                %base-user-accounts))
  (packages 
    (append
      (list vim htop nss-certs)
      %base-packages))
  (services 
    (append
      (list (service xfce-desktop-service-type)
            (set-xorg-configuration
              (xorg-configuration (keyboard-layout keyboard-layout))))
      %desktop-services))
  (bootloader
    (bootloader-configuration
      (bootloader grub-bootloader)
      (target "/dev/sda")
      (keyboard-layout keyboard-layout)))
  (file-systems
    (cons* (file-system
             (mount-point "/")
             (device (uuid "ad23de44-8331-487f-b86f-8a5f940bd702" 'ext4))
             (type "ext4"))
           %base-file-systems)))

Installer des logiciels

Les deux systèmes permettent à un utilisateur standard de gérer ses logiciels (installer, supprimer, rollbacks…).

Nix

$ nix search geany

* nixpkgs.geany (geany)
  Small and lightweight IDE
...
$ nix-env -iA nixos.geany

installing 'geany-1.36'
...
$ nix-env -q

geany-1.36
...
$ nix-env -e geany

uninstalling 'geany-1.36'
$ nix-env --list-generations

  72   2020-11-28 19:31:13   
  73   2020-12-02 21:18:48   (current)

Guix

$ guix search geany

name: geany
version: 1.37
...
$ guix install geany

Le paquet suivant sera installé :
   geany 1.37
...
$ guix packages --list-installed

geany	1.37	out	/gnu/store/bsffsj4iqaq0f14m8zpds81gklrs0n4x-geany-1.37
...
$ guix remove geany

Le paquet suivant sera supprimé :
   geany 1.37
$ guix packages --list-generations

Génération 6	02 déc. 2020 19:14:03
 + geany	1.37	out	/gnu/store/bsffsj4iqaq0f14m8zpds81gklrs0n4x-geany-1.37

Génération 7	02 déc. 2020 21:50:15	(actuelle)
 - geany	1.37	out	/gnu/store/bsffsj4iqaq0f14m8zpds81gklrs0n4x-geany-1.37

Quelques fonctionnalités pour développer

Nix et Guix sont très pratique pour un développeur. En gros, on ajoute un fichier de packaging à un projet et on peut ensuite lancer un environnement de développement, construire le projet, installer le projet comme un logiciel classique, etc.

Projet d’exemple

#include <iostream>

int main() {
    std::cout << "This is myhello!" << std::endl;
    return 0;
}
project( myhello )
add_executable( myhello myhello.cpp )
install( TARGETS myhello DESTINATION bin )

Nix

{ pkgs ? import <nixpkgs> {} }:

with pkgs; stdenv.mkDerivation {
  name = "myhello";
  src = ./.;
  buildInputs = [ cmake ];
}
$ nix-shell

[nix-shell]$ cmake -S . -B build
...

$ cmake --build build
...

$ ./build/myhello
This is hello!
$ nix-build
...

$ ./result/bin/myhello
This is hello!
$ nix-env -f . -i
...

$ myhello
This is hello!

Guix

(define-module (myhello)
  #:use-module (guix gexp) 
  #:use-module (guix packages)
  #:use-module (gnu packages cmake)
  #:use-module (guix build-system cmake))

(define-public myhello
  (package
    (name "myhello")
    (version "0.1")
    (source (local-file "" #:recursive? #t))
    (build-system cmake-build-system)
    (arguments '(#:tests? #f)) 
    (synopsis "myhello synopsis")
    (description "myhello description")
    (home-page "http://www.example.org")
    (license #f)))
$ guix environment --load-path=. myhello
...

[env]$ cmake -S . -B build
...
$ guix build --load-path=. myhello
...
/gnu/store/pxl4lx7h01a7mpn7ddqyp2r4xbdyhaxy-myhello-0.1

$ /gnu/store/pxl4lx7h01a7mpn7ddqyp2r4xbdyhaxy-myhello-0.1/bin/myhello
This is hello!
$ guix install --load-path=. myhello
...

$ myhello
This is hello!

Conclusion

Nix et Guix sont tous les deux inspirés des travaux de thèse de Eelco Dolstra (modèle de déploiement logiciel purement fonctionnel). Si la mise en œuvre diffère dans ces deux projets (implémentations, langages, etc), certaines fonctionnalités de base y sont assez similaires.

Bien-sûr, cet article n’a fait qu’effleurer le sujet. Nix et Guix ont beaucoup d’autres fonctionnalités, et c’est sur ces fonctionnalités plus avancées que les deux projets vont certainement se différencier.