lib.mkIf
Определение, описание и использование
lib.mkIf — это функция, используемая для условного определения конфигурационных опций в модулях.
lib.mapAttrsToList condition definition
Описание:
-
condition— логическое выражение (true/false); -
deffinition— значение или набор атрибутов, которые будут применены, если условие истинно.
Возвращает definition, если condition = true, иначе возвращает особое значение "пустоты".
Использование:
- Позволяет включать и выключать части конфигурации на основе условий.
Примеры
Простое условие
Исходный код:
{ config, lib, ... }:
{
config = lib.mkIf (config.networking.hostName == "webserver") {
services.nginx.enable = true;
services.nginx.virtualHosts."example.com".root = "/var/www";
};
}
Вложенные условия
{ config, lib, ... }:
{
config = lib.mkIf config.services.xserver.enable {
sound.enable = true;
hardware.pulseaudio = lib.mkIf config.services.pipewire.enable {
enable = false;
};
};
}
Комбинирование с mkMerge
{ config, lib, ... }:
{
config = lib.mkMerge [
# Общие настройки
{
environment.systemPackages = with pkgs; [ vim wget ];
}
# Условные настройки для сервера
(lib.mkIf (config.networking.hostName == "server") {
services.openssh.enable = true;
services.nginx.enable = true;
})
# Условные настройки для рабочей станции
(lib.mkIf config.services.xserver.enable {
services.xserver.desktopManager.gnome.enable = true;
hardware.bluetooth.enable = true;
})
];
}
Условное включение модуля
{ config, lib, ... }:
{
imports = [
(lib.mkIf config.virtualisation.docker.enable ./docker-extra.nix)
(lib.mkIf config.services.mysql.enable ./mysql-backup.nix)
];
}
Сложные условия
{ config, lib, ... }:
let
isProduction = config.networking.hostName == "prod-server";
hasGPU = config.hardware.opengl.enable;
in
{
config = lib.mkIf (isProduction && hasGPU) {
services.tensorflow-serving.enable = true;
services.cuda.enable = true;
};
}
Условные атрибуты в опциях
{ config, lib, ... }:
{
options.myService = {
enable = lib.mkEnableOption "My custom service";
extraConfig = lib.mkOption {
type = lib.types.str;
default = "";
};
};
config = lib.mkIf config.myService.enable {
systemd.services.my-service = {
description = "My Service";
wantedBy = [ "multi-user.target" ];
script = ''
echo "Starting my service"
${lib.optionalString (config.myService.extraConfig != "") ''
echo "Extra config: ${config.myService.extraConfig}"
''}
'';
};
};
}
Особенности использования
Правильная вложенность
# Правильно:
config = lib.mkIf condition1 {
services.xyz = lib.mkIf condition2 {
enable = true;
};
};
# Неправильно (может вызвать ошибки):
config = {
services.xyz = lib.mkIf condition1 {
enable = lib.mkIf condition2 true;
};
};
Работа с mkOverride
{ config, lib, ... }:
{
config = lib.mkIf config.services.foo.enable {
services.foo.configFile = lib.mkOverride 90 "/etc/foo/custom.conf";
# Приоритет 90 (меньше = выше приоритет)
};
}
Использование с mkDefault и mkForce
{ config, lib, ... }:
{
config = lib.mkIf config.networking.wireless.enable {
networking.networkmanager.wifi.backend = lib.mkDefault "iwd";
# Установит значение только если оно не было задано явно
};
}
Условная конфигурация сервера
{ config, lib, pkgs, ... }:
let
roles = {
web = config.node.role.web or false;
db = config.node.role.db or false;
cache = config.node.role.cache or false;
};
in
{
options.node.role = {
web = lib.mkEnableOption "Web server role";
db = lib.mkEnableOption "Database server role";
cache = lib.mkEnableOption "Cache server role";
};
config = lib.mkMerge [
# Базовая конфигурация для всех узлов
{
environment.systemPackages = with pkgs; [ htop tmux ];
services.openssh.enable = true;
}
# Конфигурация для веб-сервера
(lib.mkIf roles.web {
services.nginx.enable = true;
services.phpfpm.enable = true;
networking.firewall.allowedTCPPorts = [ 80 443 ];
})
# Конфигурация для БД сервера
(lib.mkIf roles.db {
services.postgresql.enable = true;
services.postgresql.ensureDatabases = [ "appdb" ];
networking.firewall.allowedTCPPorts = [ 5432 ];
})
# Конфигурация для кэш-сервера
(lib.mkIf roles.cache {
services.redis.enable = true;
networking.firewall.allowedTCPPorts = [ 6379 ];
})
];
}
Важные замечания
-
Ленивые вычисления:
lib.mkIfиспользует ленивые вычисления, поэтому определение вычисляется только если условие истинно. -
Обработка ошибок: Условие должно быть полностью определено. Нельзя использовать значения, которые могут быть
undefined. -
Композиция:
mkIfхорошо сочетается с другими функциями библиотеки:mkMerge,mkOption,mkDefault. -
Читаемость: Для сложных условий рекомендуется использовать
let-блоки для присвоения имен условиям. -
Отладка: Если нужно увидеть, какие условия срабатывают, можно использовать
lib.traceIfдля отладки.
Отладка условий
{ config, lib, ... }:
{
config = lib.mkIf (lib.traceValFn (v: "Condition value: ${toString v}")
(config.services.nginx.enable)) {
# конфигурация
};
}
No comments to display
No comments to display