NixOS

Un sistema operativo che utilizza Nix# per la gestione dei pacchetti e della configurazione.

Configurazione in NixOS

Prende la forma di una serie di moduli che definiscono tre elementi principali:

  1. la dichiarazione di proprietà di configurazione che hanno tipo ben definito e sono organizzate ad albero;

  2. la valorizzazione di queste proprietà ad opera dell’utente;

  3. la definizione di che configurazioni di base modificare e che pacchetti installare quando queste proprietà vengono valorizzate, attivandole.

Un breve esempio di configurazione

Il seguente esempio di configurazione di un fantomatico servizio foo: è diviso in due parti di cui la prima è preparata da uno sviluppatore, mentre la seconda è compilata da un utente.

# file modules/foo.nix
{config, pkgs, lib, ...}:
    cfg = config.services.foo;
  let
  in {
    options.services.foo = {
      enable = lib.mkEnableOption "Foo service";
      port = mkOption {
        description = '' 
          The port where the service is listening
        '';
        default = 9999;
        type = lib.types.int;
      };
    };
    config = lib.mkIf cfg.enable {
      systemd.services.foo = {
        description = "The foo service";
        wantedBy = [ "multi-user.target" ];
        script = ''
          ${pkgs.foo}/bin/foo -p ${cfg.port}
        ''
      }
    };
  }

Come puoi vedere grazie alle qualità di Nix, il modulo definisce una piccola parte della configurazione e allo stesso tempo ha riferimenti a parte di essa. In particolare la riga in cui possiamo leggere lib.mkIf cfg.enable ... si riferisce alla configurazione del sistema come definita dall’utente (di cui riporto un esempio più avanti) e nella riga successiva modifica la stessa aggiungendo un nuovo servizio.

La configurazione di base che l’utente può definire è quella che si può vedere qui (qui una versione ricercabile della stessa) o su ogni sistema NixOS eseguendo man configuration.nix.

In Nix, il solo fatto di utilizzare un pacchetto nella definizione del servizio significa includerlo nella configurazione del sistema.

Ecco qui l’ultima parte della configurazione che è sostanzialmente il punto 2 della lista precedente:

# configuration.nix
{config, pkgs, lib, ...}: {
  imports = [
    # ...
    ./modules/foo.nix
  ];
  # ...
  services.foo = {
    enable = true;
    port = 2222;
  }; 
  # ...
}

Quindi questa configurazione installerà nel sistema il pacchetto software foo e farà partire il servizio all’avvio del sistema sulla porta 2222.

Esempi più esaustivi di configurazione sono disponibili sul manuale.