Nix Flakes et les fonctionnalités équivalentes de Guix
(coopi.neocities.org)- Les Nix Flakes regroupent les dépendances d’un projet, leur verrouillage, le schéma de sortie et l’environnement de développement autour de
flake.nixetflake.lock, tandis que Guix fournit le même type de fonctionnalités via une combinaison d’outils orthogonaux comme les channels, les manifests,guix describe,guix shelletoperating-system - Les Flakes figent les dépendances via des
inputspar projet et unflake.lockgénéré automatiquement, tandis que Guix construit des environnements reproductibles avecguix describecôté utilisateur, unchannels.scmconsignant les commits du projet, etguix time-machine - La pureté est imposée dans les Flakes par une évaluation restreinte, alors que dans Guix elle est obtenue par conception grâce à la structure des modules Scheme, à des entrées explicites et à des conteneurs de build isolés
- Pour la structure des sorties, les Flakes fournissent un attrset standard comme
packages,devShellsounixosConfigurations, tandis que Guix utilise des enregistrements et fichiers Scheme transparents comme<package>, manifest,operating-systemet service, consommés directement par chaque commande - Le critère de choix est simple : si vous préférez un point d’entrée unique et un schéma standard, les Flakes conviennent mieux ; si vous préférez combiner de petits outils indépendants, Guix est plus adapté
Comparaison essentielle
- Il n’existe pas de fonctionnalité Guix unique correspondant à un flake Nix ; là où Nix Flakes résout plusieurs problèmes avec une seule grande fonctionnalité, Guix y répond par une combinaison d’outils plus petits et orthogonaux
- Guix a réutilisé le daemon de Nix et partage ses composants C++ chargés de l’isolation des builds et de la gestion du store
- Guix a réimplémenté en grande partie en Guile Scheme tout ce qui se trouve au-dessus du daemon de Nix, notamment le langage, les définitions de paquets et le système de services
- Guix et Nix partagent le format de dérivation ATerm et la lignée du daemon, mais la structure au-dessus du daemon est organisée selon la propre approche de Guix
- Guix possède les capacités offertes par Flakes, mais les présente sous une autre forme
Structure de base d’un Nix Flake
- Un Nix flake est un arbre de sources contenant un fichier
flake.nixà sa racine, généralement sous la forme d’un dépôt Git - La présence de
flake.nixfait de l’arbre de sources un flake, et le fichier suit une structure avec des éléments commedescription,inputsetoutputs descriptionest une chaîne lisible par un humain indiquant ce que le flake fournitinputsdéclare les dépendances, comme d’autres flakes, des dépôts Git ou des tarballs ; Nix les récupère, les évalue, puis les transmet à la fonctionoutputsoutputsest une fonction qui reçoit les entrées résolues et une entrée spécialeself, puis renvoie un attrset structuré contenant des paquets, des shells de développement, des configurations NixOS, des overlays, etc.-
Structure d’exemple et cibles d’exécution
- Dans l’exemple,
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";dansinputssignifie qu’on récupère la branchenixos-unstabledu dépôtNixOS/nixpkgssur GitHub - Le flake d’exemple utilise
supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" ];etnixpkgs.lib.genAttrspour générer des sorties pour plusieurs architectures CPU - Les Flakes exigent un niveau
packages.<system>et, dans l’exemple, le paquetdefaultsouspackagesest défini avecpkgs.buildGoModule src = ./.;signifie que l’ensemble du dépôt Git est utilisé comme sourcedevShellsdéfinit les shells de développement référencés parnix develop; dans l’exemple, on utilisepkgs.mkShellavecbuildInputs = with pkgs; [ go gopls gotools ];
- Dans l’exemple,
-
flake.locket évaluation pure- Lorsqu’une commande Nix est exécutée sur un flake, Nix génère le fichier JSON
flake.lock, qui fige chaque entrée et chaque dépendance transitive sur une révision précise flake.lockest un fichier de verrouillage qui permet la reproductibilité des builds d’une machine à l’autre et dans le temps- Les Flakes imposent une évaluation pure :
$NIX_PATH,builtins.currentSystemet les variables d’environnement ne peuvent pas être injectés implicitement, tout doit être explicite - Les fonctions assurées par les Flakes se résument ainsi : déclaration des dépendances, verrouillage des dépendances, application de la pureté, fourniture d’un schéma de sortie standard, partage reproductible et définition d’environnements de développement
- Lorsqu’une commande Nix est exécutée sur un flake, Nix génère le fichier JSON
L’approche équivalente de Guix
- Guix disposait déjà de solutions pour une grande partie des fonctionnalités de Flakes avant l’introduction de Flakes dans Nix 2.4 le 1er novembre 2021
- Le mécanisme de channels de Guix a été introduit vers 2018-2019
- La solution de Guix est orthogonale : elle n’adopte pas une abstraction monolithique unique et permet d’utiliser chaque outil indépendamment
-
Channels et déclaration des dépendances
- Dans un flake, les dépendances sont déclarées directement dans
flake.nix, et l’exemple utilisenixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";ainsi quehome-manager.url = "github:nix-community/home-manager"; - Dans les inputs d’un flake,
inputs.nixpkgs.follows = "nixpkgs";permet àhome-managerde ne pas reprendre son propre inputnixpkgs, mais d’utiliser celui du flake courant, ce qui évite de se retrouver avec deux copies différentes de nixpkgs - Les channels de Guix sont des dépôts Git contenant des modules Guile ; ils contiennent en général des définitions de paquets, mais peuvent aussi inclure des services, des configurations système et du code Scheme arbitraire
- Les channels de Guix sont déclarés dans
~/.config/guix/channels.scm, et ce fichier Scheme renvoie une liste d’enregistrements de channel guix pullrécupère et compile tous les channels, puis rend ces modules utilisables par toutes les commandesguix- Les channels peuvent déclarer des dépendances envers d’autres channels via le fichier
.guix-channelà la racine du dépôt - Les dépendances entre channels dans Guix sont globalement similaires aux
inputsd’un flake, et les dépendances transitives des channels sont également récupérées lors de l’exécution deguix pull
- Dans un flake, les dépendances sont déclarées directement dans
-
Dépendances par projet et dépendances par utilisateur
- Les Flakes fonctionnent par projet : chaque dépôt possède son propre
flake.nixet ses propres inputs, tandis que les channels fonctionnent au niveau système ou utilisateur, et lechannels.scms’applique à toutes les invocations deguix - Les Flakes permettent naturellement à différents projets d’avoir des ensembles de dépendances différents ; dans Guix, on utilise généralement
guix time-machineou des profils séparés pour obtenir le même effet - Les Flakes utilisent une syntaxe de type URL comme
github:NixOS/nixpkgs,git+https://..., tandis que les channels utilisent des URL Git classiques - La syntaxe des Flakes est plus ergonomique pour les références rapides, tandis que les channels sont plus simples et plus explicites
- Les Flakes prennent en charge des entrées non-flake pour des dépôts sans
flake.nixviaflake = false; - Dans Guix, un channel est un dépôt Git contenant des fichiers Scheme ; aucun opt-in particulier n’est donc nécessaire, et tout dépôt contenant des modules Guile peut devenir un channel
- Les Flakes fonctionnent par projet : chaque dépôt possède son propre
Verrouillage, reproductibilité et voyage dans le temps
-
flake.lockflake.lockest un graphe JSON dans lequel chaque input est épinglé à un hash de commit précis, et Nix vérifie lenarHash, c’est-à-dire le hash de l’arbre source complet récupéréflake.lockest commité dans le dépôt, de sorte que toute personne qui clone le projet obtient les mêmes versions de dépendances- Dans
flake.lock,originaldésigne la cible demandée etlockedla cible effectivement obtenue - Le système à deux niveaux de
flake.lockpermet des mises à jour sélectives, comme avecnix flake lock --update-input nixpkgs, en ne mettant à jour qu’un input précis tout en conservant les autres
-
guix describeetguix time-machine- Guix enregistre les commits exacts de tous les channels lors de l’exécution de
guix pull, etguix describeaffiche ces informations - La sortie de
guix describeinclut le numéro de génération, la date, l’indication du statut courant, le nom du channel, l’URL du dépôt, la branche et le commit - Les commits de channels enregistrés par Guix correspondent à un lock file, mais ils se trouvent sous la forme d’un profil Guile dans
~/.config/guix/currentplutôt que dans un fichier du répertoire du projet - Pour partager un environnement reproductible, on peut utiliser
guix time-machinedans Guix guix time-machine --commit=8a1ab328 -- shell -m manifest.scmépingle d’abord Guix à une révision donnée, puis exécuteguix shellavec les définitions de paquets de cette révisionguix time-machinetélécharge et compile cette révision si nécessaire, puis crée un environnement isolé où les définitions de paquets correspondent exactement à l’état de ce commit- Il existe aussi dans Guix un modèle consistant à versionner dans le dépôt du projet un
channels.scmcontenant des commits épinglés guix time-machine -C channels.scm -- shell -m manifest.scmreproduit exactement l’environnement en utilisant lechannels.scminclus dans le dépôt
- Guix enregistre les commits exacts de tous les channels lors de l’exécution de
-
Différences entre les deux approches
flake.lockest automatique et par projet, tandis queguix describeest automatique et par utilisateur- Un
channels.scmcontenant des commits épinglés fournit un verrouillage par projet dans Guix, mais de manière manuelle - Guix travaille à améliorer l’ergonomie du verrouillage par projet, mais le workflow actuel demande encore une configuration plus explicite
flake.lockest un graphe JSON lisible par machine, tandis que son équivalent côté Guix est un fichier Scheme listant des channels avec leurs hashes de commit- Les deux approches atteignent l’objectif d’épinglage des dépendances, mais le verrouillage des flakes est plus structuré, car il fournit un graphe complet de dépendances avec des entrées
originaletlockedpour tous les inputs transitifs guix time-machineest une fonctionnalité sans équivalent direct dans les flakes : elle permet de remonter non seulement à des versions de dépendances épinglées, mais aussi à un état historique complètement différent de la collection de paquets
Modèle de pureté
- Les Flakes s’exécutent dans un contexte d’évaluation restreint, où l’usage de
builtins.currentSystem,builtins.getEnvet de$NIX_PATHest interdit ou ignoré - Dans les Flakes, tout doit provenir des entrées déclarées, ce qui rend plus difficile la création de dépendances accidentelles à un état implicite
- Le compromis de l’évaluation pure des Flakes est qu’elle exige des paramètres
systemexplicites à de nombreux endroits pour la détection du système, et qu’elle ne permet pas de lire les variables d’environnement - Lorsqu’une échappatoire impure est nécessaire dans les Flakes, il faut passer explicitement
--impure - Guix n’a pas besoin d’un mode d’évaluation pure distinct, car l’évaluation y est déjà pure par convention
- Les modules Guile n’accèdent pas aux variables d’environnement sauf si elles leur sont explicitement transmises
- Guix n’a pas d’équivalent à
$NIX_PATH, et résout les packages via le système de modules plutôt que par un chemin de recherche - Guix n’a pas de concept équivalent à
builtins.currentSystem, et les systèmes sont spécifiés explicitement via les métadonnées des packages et l’option--system - Les builds de Guix sont également purs, et s’exécutent dans des conteneurs isolés qui ne voient que les entrées explicitement déclarées
- Dans les builds Guix, il n’y a ni
/usr/bin, ni/etc, ni accès réseau ; les exceptions d’accès réseau sont limitées aux dérivations à sortie fixe - En matière de sandboxing de build, Nix et Guix partagent fondamentalement la même approche
- Guix atteint la pureté au niveau de l’architecture grâce à la structure des modules Scheme, tandis que Flakes impose la pureté en superposant un mode d’évaluation restreint à un système initialement impur
Schéma de sortie et modèle de données
-
Schéma de sortie des Flakes
- Les Flakes définissent un schéma standard pour les outputs ;
packages.<system>.<name>est utilisé parnix build,devShells.<system>.<name>parnix develop, etapps.<system>.<name>parnix run - Le schéma de sortie des Flakes inclut aussi
nixosConfigurations.<name>,overlays.<name>,nixosModules.<name>,formatter.<system>,templates.<name>etchecks.<system>.<name> - La standardisation du schéma de sortie des Flakes permet à
nix build .,nix runetnix flake showde pointer vers des emplacements cohérents, ce qui améliore la découvrabilité - L’inconvénient du schéma de sortie des Flakes est sa rigidité ; ajouter des types de sortie arbitraires exige de modifier Nix lui-même, même s’il existe un petit mécanisme d’extension
- À cause du paramètre
<system>des Flakes, la prise en charge multiplateforme doit être gérée explicitement, et des fonctions utilitaires ou bibliothèques commeforAllSystems,flake-utilsouflake-partssont utilisées
- Les Flakes définissent un schéma standard pour les outputs ;
-
Types de données de première classe dans Guix
- Guix n’a pas de schéma de sortie unique comme Flakes, mais des types de données de première classe que différentes commandes peuvent consommer
- Dans Guix, les packages sont définis comme des enregistrements
<package>et utilisés parguix installetguix build - Dans Guix, les manifests sont définis comme des fichiers Scheme et utilisés par
guix shell -metguix package - Dans Guix, les configurations système sont définies avec
operating-systemet utilisées parguix system reconfigure - Dans Guix, les configurations home sont définies avec
home-environmentet utilisées parguix home reconfigure - Dans Guix, les services sont définis comme des enregistrements
<service>et utilisés dans le champservicesdeoperating-system - Dans Guix, les channels sont des dépôts Git et
guix pullles utilise - Dans Guix, les variantes de packages sont des procédures Scheme et
--with-inputainsi que--transformsont utilisés
-
Fichiers et définitions de packages
- Un projet Guix peut combiner et fournir un channel contenant des définitions de packages, un
manifest.scmpour le développement, unsystem.scmpour le déploiement, ainsi que des déclarationsoperating-systemouhome-environment - Dans Guix, ces fichiers n’exigent pas de fichier spécial de point d’entrée ; ce sont simplement des fichiers Scheme qui définissent des valeurs Scheme
- Dans Guix, il suffit d’indiquer le fichier à la sous-commande
guixconcernée pour que la commande le traite, sans cérémonie supplémentaire ni validation de schéma - Un exemple de
manifest.scmdéclare un environnement de développement en passant àspecifications->manifestune liste de noms de packages"guile","guile-git","guile-json" - Un exemple de
mylib.scmdéfinit un enregistrement<package>, l’équivalent dans Guix d’une dérivation Nix, dont les champs de package peuvent être interrogés de manière programmatique - Un exemple de définition de package comprend
(name "mylib"),(version "0.1.0"),(source (local-file ".")),(build-system gnu-build-system),(inputs (list guile guile-git)),(home-page "https://example.com"),(license gpl3+) - Dans Guix,
local-filerécupère au moment du build les fichiers du répertoire courant, de façon similaire àsrc = ./.;dans Nix - Dans Guix,
gnu-build-systemcorrespond à l’approche./configure && make && make install, et Guix propose aussi d’autres systèmes de build commecmake-build-systemoupython-build-system - Contrairement à Nix, où
stdenvfournit implicitementgccetcoreutils, Guix rend toutes les dépendances explicites
- Un projet Guix peut combiner et fournir un channel contenant des définitions de packages, un
Environnements de développement
- L’exemple de
devShellsdans Flakes utilisedevShells.x86_64-linux.default = pkgs.mkShell { buildInputs = with pkgs; [ go gopls gotools ]; shellHook = '' echo "Welcome to the devShell!" ''; }; mkShellcrée une dérivation qui produit un environnement shell au moment du build ;buildInputsest ajouté auPATHdu shell etshellHookexécute du bash arbitraire à l’entrée dans le shell- On entre dans un dev shell Flake avec
nix developou, pour un shell nommé,nix develop .#my-shell - Un environnement de développement Guix peut être défini dans
manifest.scmen passant une liste de chaînes de spécification de paquets àspecifications->manifest - Le manifest Guix d’exemple déclare
"go","gopls","go-tools" - On entre dans un shell basé sur un manifest Guix avec
guix shell -m manifest.scm - Guix permet aussi des environnements ad hoc sans fichier, en ne passant que des noms de paquets en ligne de commande, comme
guix shell go gopls go-tools guix shellprend en charge--containerpour une isolation complète,--emulate-fhspour exécuter des programmes qui attendent une disposition standard du système de fichiers Linux, et--nestingpour exécuter Guix à l’intérieur d’un conteneur Guix- Les manifests Guix sont des fichiers Scheme autonomes, non intégrés dans une structure
flake.nixplus large guix shellpeut fonctionner sans fichier, alors quenix developnécessite soit une flake, soit unshell.nixde l’interface historique- Flakes fournit des dev shells nommés comme
devShells.x86_64-linux.testetdevShells.x86_64-linux.default - Les manifests Guix, au lieu de proposer des dev shells nommés, reposent sur des fichiers séparés placés côte à côte, comme
manifest.scmettest-manifest.scm - Nix Flakes et Guix prennent tous deux en charge le développement conteneurisé
Configuration système
-
NixOS et Flakes
- Dans l’exemple de
nixosConfigurationsde Flakes,nixpkgs.lib.nixosSystemreçoit une liste de modules NixOS et génère une dérivation système complète incluant le noyau, les services, les fichiers de configuration, etc. - La commande d’exemple pour déployer NixOS à partir d’une flake est
nixos-rebuild switch --flake .#myhost - L’exemple de
nixosConfigurations.myhostcomprendsystem = "x86_64-linux";etmodules = [ ./configuration.nix home-manager.nixosModules.home-manager ]; - Les modules NixOS reposent sur un système de modules qui utilise
options,config,mkIf,mkDefaultetmkForceavec une fusion basée sur les priorités - Le système de modules de NixOS résout les priorités même lorsque plusieurs modules définissent la même option, ce qui facilite l’évitement des conflits même lorsque des dizaines de modules contribuent à une même configuration
- Dans l’exemple de
-
Guix
operating-system- Dans Guix,
operating-systemn’est pas une fonction mais un record Scheme, dont chaque champ est une valeur typée nommée que Guix valide - La commande d’exemple pour déployer un système Guix est
guix system reconfigure config.scm - Le record
operating-systemd’exemple inclut(host-name "myhost"),(timezone "Etc/UTC"), une configuration de bootloader, des systèmes de fichiers et des services - L’exemple de configuration du bootloader Guix utilise
grub-efi-bootloaderavec la cible"/boot/efi", et Guix prend en charge GRUB, U-Boot, etc. - Les systèmes de fichiers Guix sont déclarés sous forme de liste, et
%base-file-systemsfournit des valeurs par défaut pour/dev,/proc,/sys, etc. - Les services Guix forment un graphe orienté acyclique (DAG), et chaque service peut étendre d’autres services
%base-servicesfournit les services essentiels comme le système d’init Shepherd, syslog et le réseau- La configuration système Guix n’a pas besoin d’un type de sortie spécial : il suffit d’indiquer à
guix systemun fichier qui retourne un recordoperating-system - La composition des services dans Guix facilite l’écriture de nouveaux services qui se branchent sur un système existant de manière arbitraire
- Dans Guix,
Découvrabilité et registre
- Flakes dispose de
flake.nix, un point d’entrée standard où sont déclarés dans un seul fichier les dépendances du projet, les sorties et un schéma découvrable - Un projet Guix peut utiliser des fichiers conventionnels comme
manifest.scm,channels.scm,guix.scmoupackage.scm - Il existe une volonté de standardiser
guix.scmcomme fichier de projet reconnu automatiquement parguix shell, mais cela reste moins établi queflake.nix - Flakes dispose du registre global flake-registry, qui mappe des noms courts vers des URL ; exemples :
nix run nixpkgs#hello,nix build github:NixOS/nixpkgs#firefox - Guix utilise des spécifications de paquets pour une commodité similaire, par exemple
guix shell helloetguix install firefox - Guix n’a pas d’équivalent de registre permettant de désigner un dépôt Git arbitraire par un nom court, et utilise directement les URL
- Le registre Nix a parfois été source de confusion, car il n’est pas toujours clair si
nixpkgsest une entrée du registre, un chemin local ou une autre cible nix flake showest une commande qui affiche sous forme d’arborescence tout ce qu’une flake fournit- Guix propose
guix searchpour les paquets etguix system searchpour les services, mais il n’existe pas de commande équivalente pour afficher tout ce qu’un projet ou un dépôt donné fournit ; il faut inspecter directement les fichiers Scheme - Flakes est fort en découvrabilité dans la mesure où
nix flake showdonne une vue cohérente de ce que fournit un projet - Les projets Guix sont plus ad hoc : il faut savoir quels fichiers consulter, et il n’existe pas de fichier standard à point d’entrée unique
- Guix est très flexible, car tout étant en Scheme, on peut définir et combiner ce que l’on veut sans schéma
Modèle de paquets et réécriture de graphe
- Dans Nix, un paquet est une fonction qui renvoie une derivation via un appel à
stdenv.mkDerivation { ... }, et le résultat est un ensemble d’attributs opaque - Dans Guix, un paquet est un enregistrement
<package>, c’est-à-dire une structure de données transparente avec des champs nommés, que l’on peut inspecter, transformer et combiner avec des procédures Scheme standard - Les définitions de paquets de Guix sont des enregistrements transparents plutôt que des fonctions opaques, ce qui permet d’effectuer l’inspection et les transformations de manière programmatique sans outillage spécial
- Dans Guix, les paquets étant des données, il est facile d’effectuer des réécritures de graphe
- Dans Guix,
package-input-rewritingpermet d’exprimer le remplacement deperlparperl-minimalen parcourant l’ensemble du graphe de dépendances - Le mot-clé
inheritde Guix redéfinit un paquet en héritant de tous les champs decoreutilspuis en ne surchargeant que les champs spécifiés - Nix dispose d’overlays à visée similaire, mais leur utilisabilité est moindre, car l’inspection et la transformation sont plus difficiles à cause de l’interface en fonctions opaques
Mises à jour de sécurité, bootstrap et authentification
- Le grafting de Guix permet d’appliquer des mises à jour de sécurité dans l’arbre de dépendances sans reconstruire tous les paquets dépendants
- Lorsqu’une vulnérabilité touche une bibliothèque bas niveau comme glibc, Guix peut réécrire les chemins du dépôt pour les remplacer par une version corrigée
- Nix reconstruit tout en cas de mise à jour de sécurité, et sur de grands arbres de dépendances, le temps de build peut différer de plusieurs heures
- Guix met fortement l’accent sur le bootstrap à partir du code source, ce qui permet de construire l’ensemble du système à partir d’une petite base de confiance
- La chaîne de bootstrap de Guix commence avec un assembleur hexadécimal d’environ 500 octets, puis passe au compilateur C
mesécrit en Scheme, àtcc, puis à l’ensemble de la GNU toolchain - Le projet bootstrappable builds traite en détail du bootstrap complet à partir des sources
- Nix dépend de davantage de graines binaires que Guix
- Si la chaîne de bootstrap ne peut pas être auditée, on ne peut pas vérifier complètement que le système a bien été construit à partir des sources prévues ; le bootstrap complet à partir des sources est donc important pour la confiance et la vérifiabilité
- Les channels Guix prennent en charge par défaut une authentification cryptographique
- Un channel Guix spécifie une « introduction » composée d’un commit précis et de sa signature Ed25519, et Guix vérifie toute la chaîne de signatures depuis cette introduction jusqu’au commit actuel
- Les Flakes utilisent HTTPS et l’infrastructure GitHub comme modèle de confiance, ce qui constitue un modèle de sécurité différent de l’authentification des channels Guix par Ed25519
Correspondances clés du tableau récapitulatif
- Pour la déclaration des dépendances, Flakes utilise les
inputsdeflake.nix, tandis que Guix utilisechannels.scmet.guix-channel - Pour le verrouillage des dépendances, Flakes utilise
flake.lockautomatiquement et par projet, tandis que Guix utiliseguix describeautomatiquement par utilisateur etchannels.scmavec spécification manuelle de commits par projet - L’évaluation pure est imposée en mode flake, tandis que dans Guix, elle est inhérente à la conception
- Pour le schéma de sortie, Flakes utilise un attrset structuré dans
outputs, tandis que Guix utilise des enregistrements Scheme ad hoc - Pour les environnements de développement, Flakes utilisent
devShellsetnix develop, tandis que Guix utilisemanifest.scmetguix shell - Pour la configuration système, Flakes utilisent
nixosConfigurationset le système de modules, tandis que Guix utiliseoperating-systemet un DAG de services - Pour la reproductibilité en une seule commande, Flakes utilisent
nix build github:foo/bar, tandis que Guix utilise la formeguix time-machine -C channels.scm -- build - Pour le verrouillage par projet, Flakes le gèrent automatiquement avec
flake.lock, tandis que Guix le gère manuellement avecchannels.scmcontenant les commits - Pour l’explorabilité, Flakes utilisent
nix flake show, tandis que Guix s’appuie sur l’inspection des modules Scheme - Pour le modèle de paquets, Flakes/Nix utilisent des fonctions opaques, tandis que Guix utilise des enregistrements transparents
- Pour l’init system, Nix utilise systemd, tandis que Guix utilise GNU Shepherd
- Pour les mises à jour de sécurité, Nix reconstruit tout, tandis que Guix utilise un grafting rapide
- Pour la confiance dans le bootstrap, Nix repose sur des graines binaires, tandis que Guix repose sur un bootstrap complet à partir des sources
- Pour les mises à jour authentifiées, Flakes reposent sur la confiance dans HTTPS/GitHub, tandis que Guix utilise l’authentification des channels par Ed25519
- Pour la prise en charge de la FHS, Nix propose
buildFHSUserEnv, tandis que Guix propose--emulate-fhs - Pour la prise en charge hors Linux, Nix propose nix-darwin pour macOS, tandis que Guix est structuré autour de GNU Hurd
- Concernant l’exclusivité au logiciel libre, Nix n’est pas exclusivement libre et peut être configuré, tandis que Guix respecte les FSDG
Conclusion
- Flakes et Guix résolvent le même type de problèmes — reproductibilité, gestion des dépendances et déclaration du système — avec des philosophies d’architecture différentes
- Flakes se rapproche d’une fonctionnalité unique avec un fichier, un schéma, un fichier de verrouillage et un ensemble de conventions
- Guix est une combinaison d’outils orthogonaux comme les channels pour la distribution, les manifests pour les environnements,
operating-systempour la configuration,guix time-machinepour la reproductibilité, et les enregistrements Scheme pour d’autres structures - Si l’on préfère une seule manière standard, un seul fichier d’entrée, un seul schéma de sortie et un seul format de verrouillage, Flakes est un choix naturel
- Si l’on préfère une approche qui applique à la gestion de paquets la philosophie Unix consistant à combiner de petits outils indépendants dont chacun fait bien une chose, Guix convient bien
- Les deux écosystèmes se sont développés autour de l’idée que la gestion de paquets doit être fonctionnelle, déclarative et reproductible, et poussent cette même idée avec des implémentations différentes
1 commentaires
Avis sur Lobste.rs
Ce site est beaucoup trop pénible à lire sur mobile : le texte est un peu petit, et il interrompt sans arrêt au moindre défilement
Après la première comparaison, je n’arrivais plus à lire, parce que ça remontait sans cesse à la table des matières
Même après avoir lu l’article, je ne comprends toujours pas très bien comment on est censé spécifier et figer les dépendances d’un projet. Pour le déployer et le partager, on dirait qu’il faut retrouver manuellement le hash de commit de chaque dépendance transitive et le mettre dans
channels.scmtime-machinesemble ne fonctionner que sur l’ensemble de paquets Guix, pas sur les dépendances hors arborescenceAvec Nix, on peut aussi exécuter assez facilement l’état passé de nixpkgs avec quelque chose comme
nix run github:nixos/nixpkgs/<commit hash>#<package>Ce qui est particulier avec Guix, c’est qu’il ne sépare pas la version de la collection de paquets de la version du gestionnaire de paquets. Si on veut exécuter un ancien paquet, on finit aussi par lancer une ancienne version de Guix, et je ne vois pas bien pourquoi on voudrait ça
L’article dit que les flakes obligent à retrouver les commits manuellement, puis juste après il donne en exemple une commande Guix où il faut justement préciser un commit. On peut aussi remplacer la version de nixpkgs dans un Nix flake avec
--override-input, mais c’est assez sale, et c’est d’ailleurs un des points qu’unflake essaie d’améliorerEn général, on développe dans un environnement
guix shelldédié, puis quand vient le moment de partager, on enregistre tous les hashes de commit danschannels.scmavecguix describe -f channels > channels.scmDans la doc declaring channel dependencies, on voit qu’on peut préciser les commits des dépendances, mais il ne semble pas y avoir d’option pour vérifier qu’une dépendance qui dépend elle-même d’autre chose est bien figée sur des commits précis elle aussi
La notation
--commit=detime-machinecorrespond à un canal Guix, mais on peut aussi charger des canaux supplémentaires depuis un fichier avec-CCela a l’avantage de ne pas perdre l’historique ni la reproductibilité même quand il y a des changements incompatibles dans le gestionnaire de paquets et les enregistrements de paquets
En revanche, cela demande un checkout de nixpkgs pour chaque commit, donc le coût initial de construction serait énorme. Une fois l’index créé, le coût pour le maintenir serait faible
J’ai signalé le problème du site et ce fil à coopi, donc j’espère que ce sera corrigé bientôt
Même si je penche complètement du côté de Guix, j’aimerais bien, comme le dit coopi, que Guix ait lui aussi un fichier/répertoire standard comme
flake.nixou un répertoirenixqui contienne tout. Cela dit, comme il faut indiquer le bon chemin pour importer les modules Scheme, ce n’est peut-être pas possibleCe post Lobsters contient bien ce dont parle l’auteur, donc les tags
nixetlispme semblent suffisantslinux. C’est le seul noyau qu’ils ont en commun tous les deux :P En revanche, comme tu le dis,unixn’est probablement pas pertinentPar exemple, quelque chose comme ça : Et ce serait bien d’avoir aussi une commande
guix channelpour faciliter la création et la gestion de nouveaux canauxJe me demande si Guix a aussi une fonctionnalité comme
.inputs.nixpkgs.followsdans les Nix flakes, pour remplacer le figement des dépendances transitivesEt une bonne partie de la description de Guix par l’auteur fait penser au Nix d’avant les flakes : pas de point d’entrée standard, usage de canaux, etc. Cela dit, avec Guix, le système de formats et le fait d’avoir un vrai langage rendent ce genre de schéma moins pénible. On dirait une histoire alternative de ce qu’aurait pu être Nix s’il avait été meilleur, ou écrit dans un autre langage
À cause des problèmes d’ergonomie signalés dans d’autres commentaires, j’hésite à recommander l’article. Comme j’utilise NoScript avec JavaScript désactivé par défaut, je ne m’en étais pas rendu compte
Cela dit, ce texte arrive au bon moment. Dans mon entreprise, on s’oriente vers un usage massif de Nix, et on galère un peu avec les flakes ; les explications ici m’ont semblé bien plus claires que tout ce que j’avais lu auparavant
Réponse de Coopi : il a fait une modification ce matin, mais n’a pas pu la tester à cause du travail, et il s’est avéré qu’il y avait un problème dans le JavaScript
Ce site est inutilisable sur mobile iOS. On dirait que la page se charge en bas puis remonte immédiatement vers le haut, et dès que je descends de plus d’un écran, quelque chose se déclenche et me remonte encore
Le mode lecture fonctionne, mais on perd la mise en évidence et les détails de style qui étaient pourtant plutôt réussis
Il est juste de dire que ce que font les Nix flakes peut aussi se faire avec plusieurs outils Guix, mais il faut aussi rappeler que Nix avait déjà, et a toujours, de petits outils orthogonaux pour résoudre les mêmes problèmes
Ce que les flakes apportent, c’est un point d’entrée standard pour les projets et l’écosystème que cela rend possible, par exemple le registre. L’article dit d’ailleurs que Guix n’a pas cet équivalent
Les utilisateurs de Guix peuvent considérer qu’un point d’entrée standard n’est pas nécessaire, et beaucoup d’utilisateurs de Nix l’ont pensé aussi
Mais dire qu’on peut faire des flakes avec un ensemble d’outils orthogonaux, c’est un peu comme dire que FreeBSD n’a pas besoin de support OCI puisque les jails permettent déjà de tout faire. Cela passe à côté du fait que la standardisation rend possible tout un écosystème
Je m’intéresse beaucoup à Guix et j’y ai même un peu contribué, mais j’aimerais comparer pourquoi construire avec
guix time-machineetchannels.scmprend tellement plus de temps que modifier le verrouillage d’un flake puis évaluer Nix. Si c’était juste trois fois plus lent — par exemple passer de 5–10 secondes à 15–30 secondes — je pourrais l’accepter, mais ce n’est pas du tout l’impression que j’ai eue en essayant