Useful Nix

Модули

NixOS предоставляет возможность настраивать систему с помощью модулей, позволяя сделать систему более гибкой. Модули представляют собой отдельные файлы с расширением .nix, в которых содержится различная конфигурация. Например, стандартный файл конфигурации /etc/nixos/configuration.nix - тоже модуль.

По сути каждый файл с расширением .nix это модуль, а если быть точнее функция Nix.

Структура

Модули имеют следующий синтаксис:

{
  imports = [
    # Пути к другим модулям, включенными в данный
  ];
  options = {
    # Объявления опций
    # Чаще всего включает опцию enable (по умолчанию false)
  };
  config = {
    # Определения опций
    # Например, для опции enable добавляет systemd службу
    # А для extraConfig записывает его содержимое в файл с конфигурацией
  };
}

Если вам не нужно объявлять опции, существует запись короче:

{
  imports = [ ... ];

  # Config секция
  services.somemodule.enable = true;
  # Обертку config = { } можно опустить
}

Функция

Модуль может быть функцией, принимающей набор атрибутов:

{ config, pkgs, ... }: {
  ...
}

По умолчанию доступны следующие аргументы:

  • config - конфигурация системы
  • options - все объявления опций
  • lib - стандартная библиотека nixpkgs (pkgs.lib)
  • pkgs - набор атрибутов из nixpkgs, настроенный через nixpkgs.config
  • modulesPath - расположение каталога с модулями

... позволяет функции принимать неограниченное количство других аргументов. Чаще всего необходимо, иначе будет возникать ошибка из-за непредвиденных аргументов.

Пользовательские аргументы можно передавать, например, с помощью specialArgs во флейке.

Импорты

Импорты - пути к другим модулям, которые должны быть включены в конфигурацию. Набор модулей по умолчанию можете найти здесь. Чтобы их использовать, не нужно из добавлять в список импорта. Эти модули как раз содержат все стандартные опции NixOS (например, programs.git).

Декларации

Декларации определяют внешние параметры модуля

optionName = mkOption {
  ...
}

Они создаются через функцию mkOption, принимающюю следующие аргументы:

  • type - тип параметра
  • default - значение параметра по умолчанию
  • example - пример, который будет показан на NixOS Wiki
  • description - описание, которое будет показано на NixOS Wiki

Помимо этого существуют еще две функции-обертки над mkOption:

  • mkEnableOption - создает параметр enable, принимает один аргумент - имя программы/сервиса
  • mkPackageOption - создает параметр package, принимает три аргумента: переменную пакетов (pkgs, как правило), имя программы/сервиса и аттерсет с пятью параметрами (nullable, default, example, extraDescription, pkgsText)

Пример

Создайте в одной папке с вашим файлом конфигурации файл hello.nix:

hello.nix
{ lib, pkgs, config, ... }: with lib; let
  # Просто укороченное имя для окончательных настроек, установленных пользователем
  # cfg - общее соглашение
  cfg = config.services.hello;
in {
  # Здесь мы объявляем все настройки для сервиса hello
  options.services.hello = {
    enable = mkEnableOption "hello service";
    package = mkPackageOption pkgs "hello" {
      default = pkgs.hello;
    };
    greeter = mkOption {
      type = types.str;
      default = "World";
    };
  };

  # Включаем systemd службу hello если пользователь установит services.hello.enable = true;
  config = mkIf cfg.enable {
    systemd.services.hello = {
      wantedBy = [ "multi-user.target" ];
      serviceConfig.ExecStart = "${getExe cfg.package} -g 'Hello, ${escapeShellArg cfg.greeter}!'";
      # getExe - функция для получения бинарника прогаммы, по другомо можно написать ${pkgs.hello}/bin/hello
      # escapeShellArgs - функция для безопасной передачи аргументов в оболочку
    };
  };
}

Теперь мы можем в нашем конфигурационном файле настроить сервис hello:

{
  imports = [ ./hello.nix ];
  ...
  services.hello = {
    enable = true;
    greeter = "Bob";
  };
}

Это запустит systemd службу hello, которая выводит текст "Hello, Bob!"

On this page