Конфигурация и модули
Модуль
Модуль – это шаблон или функция, описывающая, как настроить определенный компонент системы.
Модуль описывает, как что-то должно работать, его параметры и настройки. Например, модуль для nginx описывает, как настроить веб-сервер, но не указывает, какие сайты будут на нем размещаться.
Модули позволяют разбивать настройку системы на управляемые части, делая ее более структурированной, повторно используемой и масштабируемой.
Функции модуля
- Абстракция. Модули скрывают детали реализации, предоставляя стандартизированный интерфейс для настройки компонентов системы. В этом смысле он больше похож на описание и функциональность класса в языке программирования.
- Повторное использование. Один и тот же модуль может использоваться в разных частях системы или в разных конфигурациях для однотипных настроек.
- Использование других модулей. Модули могут импортировать другие модули, позволяя создавать иерархическую структуру конфигурации.
Структура модуля
- Импорт других модулей(imports).
- Объявление параметров(options).
- Определение параметров(config).
{
imports = [
# Пути к другим модулям.
# Модули могут импортировать другие модули, позволяя
# создавать иерархическую структуру настроек.
];
options = {
# Объявление параметров.
# Объявляет какие настройки пользователь этого модуля может устанавливать.
# Обычно это включает общий пункт "enable" изначально установленный в ложное значение.
};
config = {
# Определение параметров.
# Определяет какие другие настройки, службы и ресурсы должны быть задействованы.
# Обычно это зависит от того выбрал ли пользователь этого модуля
# пункт "enable" используя объявление выше.
# Параметры для модулей импортированных в секции "imports" могут быть установлены здесь.
};
}
Каждый модуль может объявлять новые параметры, которые являются настройками для компонентов системы. Например, модуль для настройки веб-сервера может иметь параметры порта и директории сайта.
Все модули получают доступ к переменной config, которая содержит текущие значения параметров из других модулей, что позволяет модулям взаимодействовать друг с другом и использовать ранее определенные настройки.
Поскольку модули описывают желаемое состояние системы, а не шаги по его достижению, NixOS является декларативной системой, где настройка системы осуществляется средствами модулей.
Примеры использования модулей
- Управление службами. Модуль может описывать настройку и запуск службы, например, веб-сервера nginx, включая его настройку и зависимости.
- Настройки пользователя. NixOS home-manager использует модули для управления настройками пользователя и содержимым его домашнего каталога, например, настройками оболочки или приложения.
- Пакеты. Модули могут описывать сборку и установку пакетов, а также управлять их зависимостями.
Преимущества модулей
- Воспроизводимость. Модули упрощают создание воспроизводимых настроек, которые можно легко применить на разных машинах.
- Управление. Разбиение настроек на модули делает ее более управляемой и понятной, даже для сложных систем.
- Повторное использование. Модули могут быть повторно использованы в разных настройках, что сокращает дублирование кода.
Вложенные модули
Вложенные модули - это тип, позволяющий определять вложенные модули с собственным набором параметров. Он используется для структурирования сложных настроек, группируя связанные параметры в отдельный блок.
При использовании lib.types.submodule вы создаёте новый параметр, значением которого будет набор атрибутов, соответствующих другому, вложенному модулю. Этот вложенный модуль имеет свой собственный набор параметров, как и обычный модуль NixOS.
Пример:
Допустим, вы создаёте модуль для веб-сервиса, и хотите, чтобы опции для базы данных были сгруппированы.
- Объявление типа
submodule:
Вы определяете параметрdatabaseс типомsubmodule. Внутриsubmoduleвы задаёте собственные параметры, например,host,portиuser.
# module.nix { config, lib, ... }: let types = lib.types; in { options.database = lib.mkOption { type = types.submodule { options = { host = lib.mkOption { type = types.str; default = "localhost"; }; port = lib.mkOption { type = types.int; default = 5432; }; user = lib.mkOption { type = types.str; default = "admin"; }; }; }; description = "Настройки для базы данных."; }; } - Использование в настройке:
Затем в вашей настройке вы можете определить значения для этих вложенных параметров.
# configuration.nix { ... }: { imports = [ ./module.nix ]; database = { host = "db.example.com"; port = 5433; user = "web_user"; }; }
В результате вы получите настройки, где config.database.host будет "db.example.com", config.database.port будет 5433 и config.database.user будет "web_user".
Преимущества
- Модульность: Позволяет разбивать сложные настройки на логические, повторно используемые блоки.
- Структурирование: Повышает читаемость и удобство управления настройками.
- Типобезопасность: Каждый параметр внутри
submoduleимеет свой тип и проверяется, что предотвращает ошибки настройки. - Совместимость с другими типами: Часто используется в сочетании с
lib.types.attrsOfилиlib.types.listOfдля создания списков или наборов подмодулей. Например, можно создатьlistOf submodulesдля определения нескольких веб-сервисов с похожими настройками.
Конфигурация
Конфигурация – это конечный файл (например, configuration.nix), который использует эти модули для сборки всей системы, применяя конкретные настройки.
Внутри файла конфигурации вы импортируете и используете модули, задавая им конкретные значения. Например, вы можете указать, какие сайты разместить на nginx, используя для этого модуль.
Конфигурация описывает всю вашу систему в целом, интегрируя различные модули и их настройки в единое целое.