Skip to content
Snippets Groups Projects
Lzebulon's avatar
lzebulon authored
5acc5cb8

Configuration NixOS au Crans

Voici la configuration NixOS du Crans.

Les fichiers README.md des différents dossiers devraient indiquer assez précisément le rôle du dossier (et si ce n'est pas le cas, fais de la doc !).

Table des matières

  1. Nix et NixOS
    1. Nix
    2. NixOS
    3. Nix Store
    4. Flakes
  2. Rôles des fichiers et sous-dossiers
    1. Fichiers flake
    2. Secrets
    3. Machines
    4. Modules
    5. Devshells
  3. Commandes utiles
    1. Commandes pour les flakes
    2. Commandes pour NixOS
    3. Commandes pour les devshells
    4. Commandes pour le Nix Store

Nix et NixOS

Voici une petite introduction de ce que sont nix et NixOS. Le but n'est pas de faire un véritable tutoriel mais plutôt faire des rappels qui peuvent toujours être utiles (ou pour les nouveaux et nouvelles apprenti⋅e⋅s !).

NixOS est une distribution Linux basé sur une configuration déclarative, permettant ainsi une reproducibilité. Cette configuration est écrite dans le langage nix. N'ayez pas peur de ce langage, on peut le décrire comme une version plus expressive du JSON (avec des variables, des fonctions, ...).

Nix

En lisant quelques fichiers de configuration, vous devriez rapidement comprendre la syntaxe de nix (qui n'est pas très complexe). Voici une liste non exhaustive de subtilités que vous pouvez rencontrer dans la configuration NixOS du Crans qu'il faut avoir en tête en lisant du code nix :

  • nix est typé et, dans la grande majorité des cas, ne pourra pas être exécuté si les types ne sont pas respectés. Les types les plus importants sont : les nombres (ex : 1), les chaînes de caractères (ex : "toto1234"), les listes (ex d'une liste de nombres : [ 1 10 1234 ], attention il n'y a pas de séparateur entre les éléments), les ensembles (ex : { a = "foo"; b = 3; }), et les fonctions (ex : x: x + 1 qui correspond à une fonction qui à x associe x + 1). Vous trouverez plus de détails sur cette page.

  • Les codes a.b = 3; et a = { b = 3; }; sont sémantiquement équivalents : cela signifie que vous pouvez changer l'un en l'autre et réciproquement. Usuellement, la première version n'est utilisé que lorsque a n'a qu'un seul attribut.

  • La variable config contient toute la configuration actuelle : elle permet d'utiliser des valeurs déclarées dans un autre fichier et susceptibles d'être modifiées dans le futur sans que cela ne pose de problème. Cela sera très utile notamment pour age (voir secrets/README.md).

  • Lorsque vous importez d'autres fichiers avec imports, vous ne pouvez qu'importer des fichiers. Si vous importez un dossier, cela n'aura pour effet que d'importer le fichier default.nix du dossier importé.

NixOS

NixOS se construit (build en anglais) sous forme de dérivations (voir la partie sur le Nix Store pour plus d'explications). Celles-ci contiennent l'intégralité de la configuration au moment du build, ce qui est forcé par le fait que l'évaluation se fait de façon pure, c'est-à-dire qu'il n'est pas possible d'utiliser des éléments en dehors de la configuration pour écrire la configuration. Cela est forcé par l'utilisation des flakes (voir la partie consacrée aux flakes).

Dans cette configuration, et grâce à l'utilisation des flakes, il est possible d'écrire la configuration de plusieurs machine dans ce même dépôt git. Chaque machine sous NixOS aura donc le code de chaque autre machine inscrite dans la configuration, mais du fait que nix s'évalue de manière paresseuse, chaque machine n'évaluera et ne compilera que ce qui est nécessaire pour sa propre configuration.

Pour trouver des options pour décrire la configuration d'une machine, rendez-vous sur le saint graal de nixpkgs (le dépôt contenant tous les logiciels et librairies packagés pour nix, le package manager du même nom que le langage), et de NixOS : https://search.nixos.org/. Vous pouvez également trouver de l'aide pour la configuration de services sur https://nixos.wiki/.

Nix Store

Le Nix Store est une abstraction permettant de stocker de manière immuable des données utiles au package manager nix et à NixOS (comme les dérivations, les sources de packages, les packages eux-mêmes, ...). On peut découper le Nix Store en plusieurs parties, les principales étant le dossier /nix/store en local, ou les différents caches contenant des binaires pour éviter la recompilation de tous les packages (le principal étant situé à https://cache.nixos.org).

Il est important de noter que /nix/store est un dossier monté en lecture seule et est visible par tous les utilisateurices. Il est donc crucial de ne jamais laisser apparaître de mot de passe en clair dans cette configuration, car celui-ci serait alors lisible par tous les utilisateurices ayant accès à la machine. L'utilisation de Sops (voir secrets/README.md) permet de palier ce problème en introduisant des secrets chiffrés uniquement accessibles pour les machines devant y avoir accès et pour les nounous.

Bien que ce que les fonctionnalités de Nix exposées dans cette documentation sont pures, Nix a besoin d'un état interne. Les fichiers stateful de Nix se trouvent dans le dossier /nix/var. Ce dossier contient notamment les logs de Nix, ainsi qu'une base de donnée Sqlite, les profiles Nix, etc. Certains de ces fichiers ne sont pas primordiaux (e.g. les logs), mais d'autres le sont. Par exemple, la BDD (accessible au chemin suivant : /nix/var/db/db.sqlite) est nécessaire au bon fonctionnement de Nix. Une corruption de cette BDD peut entrainer le dysfonctionnement du système (e.g. ne plus pouvoir faire de maj).

Flakes

Le fichier flake.nix dénote de tous les autres fichiers de cette configuration : celui-ci est une flake, à savoir l'unité de permettant de packager du code nix de manière reproducible. Plus simplement, dans notre cas, cette flake contient toutes les sources utilisées dans la configuration pour pouvoir être évaluée, ainsi que toutes les sorties, à savoir les configurations de toutes les machines, ainsi que les shells de développement (voir la partie sur les devshells).

Rôles des fichiers et sous-dossiers

Fichiers flake

Les fichiers flake.nix et flake.lock sont respectivement la flake de cette configuration et le lockfile associé. Le lockfile est généré automatiquement par certaines commandes et ne doit pas être modifié à la main : il s'agit, à la manière d'un Cargo.lock pour Rust ou d'un package-lock.json pour Node.js, d'un fichier décrivant précisément les versions des dépendances utilisées pour compiler/exécuter le projet.

Secrets

Le fichier secrets.nix contient la description des secrets et des clefs GPG utilisées par age, tant par les machines que par les nounous. Le dossier secrets contient tous les secrets nécessaires aux machines lors de la construction de leur configuration. Vous pouvez voir plus de détails dans secrets/README.md.

Machines

Le dossier hosts contient la configuration unique à chaque machine. On y retrouve en particulier le bootloader, le déchiffrement des secrets nécessaires pour la machine et la configuration réseau. En effet, il est utile de rappeler qu'aucune machine du Crans (hors VM adhérent⋅e⋅s) n'utilise du DHCP : il est donc nécessaire d'écrire à la main toutes les interfaces dont elles disposent. Pour plus de détails sur les interfaces réseaux, vous pouvez vous réferer à la documentation des VLAN, et à hosts/README.md de manière plus générale.

Modules

Le dossier modules contient l'ensemble des options qui peuvent être partagées par plusieurs configurations de machines. Vous pouvez voir plus de détails dans modules/README.md.

Devshells

Le dossier devshells contient des environnements de travails pouvant être utilisés par tout utilisateurice. Ceux-ci permettent d'ajouter temporairement des paquets à l'environnement de travail (dont le shell bash ou équivalent), permettant ainsi d'avoir facilement (voir la partie sur les commandes liées aux devshells) tous les outils nécessaires au développement/débuggage. Vous pouvez voir plus de détails dans devshells/README.md.

Commandes utiles

Pour toutes les commandes présentées, on débutera la ligne de commande par $ si tout utilisateurice peut l'exécuter, et # s'il faut les droits super-user.

Commandes pour les flakes

  • Vérification de la validité de la flake

    $ nix flake check [path]
  • Mise à jour d'une dépendance dans la flake (mettra à jour le lockfile)

    $ nix flake lock --update-input [input name]
  • Mise à jour de toutes les dépendances de la flake (mettra à jour le lockfile)

    $ nix flake update

Commandes pour NixOS

  • Regénération de la configuration sans modifier la configuration, utile pour tester une configuration

    $ nixos-rebuild dry-build
  • Regénération de la configuration en remplaçant la configuration courante (ne fera rien si la configuration contient des erreurs)

    # nixos-rebuild switch

Commandes pour les devshells

  • Utilisation d'un devshell

    $ nix develop [url]

    Par exemple, pour utiliser le devshell par défaut et que cette configuration est située dans /etc/nixos, la commande pourra être : nix develop /etc/nixos#default. Vous pouvez par ailleurs omettre #default, et sans dossier indiqué le dossier courant sera utilisé, on peut donc écrire nix develop pour utiliser le devshell par défaut si le dossier courant est /etc/nixos.

Commandes pour le Nix Store

  • Supprimer toutes les entrées du Nix Store non utilisées

    $ nix-store --gc # "gc" pour garbage collect
  • Supprimer toutes les objets non atteignables dans le Nix Store

    # nix-collect-garbage -d
  • Optimiser les liens symboliques dans le Nix Store (permet de gagner de l'espace de stockage)

    $ nix-store --optimise