Оверлеи
В отличие от рассмотренных в предыдущей главе оверрайдов, создающих новый локальный derivation, оверлеи позволяют изменить pkgs
, меняя один derivation на другой.
В классическом Nix оверлеи можно задать в ~/.config/nixpkgs/overlays.nix
или ~/.config/nixpkgs/overlays/*.nix
, однако во флейках такой подход неприменим, поскольку они не могут полагаться на конфиги, лежащие вне гит-репозиториев. Вместо этого Home Manager и NixOS предоставляют опцию nixpkgs.overlays
:
Так фичи используются на примере модуля, который можно подгрузить в NixOS или Home Manager (т.к. названия функций/опций те же, работать будет и там, и там):
{ config, pkgs, lib, ... }:
{
nixpkgs.overlays = [
# Overlay 1: используем `self` и `super`, косим под наследование
(self: super: {
google-chrome = super.google-chrome.override {
commandLineArgs =
"--proxy-server='https=127.0.0.1:3128;http=127.0.0.1:3128'";
};
})
# Overlay 2: Используем `final` и `prev` для обозначения "нового" (измененного) и старого derivation-ов
(final: prev: {
steam = prev.steam.override {
extraPkgs = pkgs: with pkgs; [
keyutils
libkrb5
libpng
libpulseaudio
libvorbis
stdenv.cc.cc.lib
xorg.libXcursor
xorg.libXi
xorg.libXinerama
xorg.libXScrnSaver
];
extraProfile = "export GDK_SCALE=2";
};
})
# Overlay 3: спрятался в файл.
# Содержимое файла выглядит как первый или второй пример:
# `(final: prev: { xxx = prev.xxx.override { ... }; })`
(import ./overlays/overlay3.nix)
];
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Первый оверлей меняет google-chrome
, добавляя параметр командной строки, задающий прокси-сервер. Второй - добавляет к derivation-у стима ряд доплнительных зависимостей и экспортирует переменную окнужения. Третий оверлей лежит в отдельном файле.
По аналогии несложно писать кастомные оверлеи.
Modular overlays
В предыдущем примере все оверлеи лежали в одном файле (или импортировались руками), неудобство такого подхода растет пропорционально количеству оверлеев. Вместо этого можно класть каждый оверлей в отдельный файл и импортировать их автоматичеси.
Для начала создаем директорию overlays
там же, где лежит основной конфиг. Туда кладем default.nix
с таким содержимым:
# Импортируем все .nix-файлы в текущей директории, выполняем, передавая на вход args
# На выходе имеем список (list) результатов их выполнения, т.е. оверлеев
args:
builtins.map
(f: (import (./. + "/${f}") args)) # импортируем и выполняем файлы с оверлеями
(builtins.filter # ищем все файлы с оверлеями в текущей директории
(f: f != "default.nix") # пропускаем сам `default.nix` во избежание бесконечной рекурсии
(builtins.attrNames (builtins.readDir ./.)))
2
3
4
5
6
7
8
9
default.nix
импортирует и выполняет все .nix
-файлы, лежащие в директории с ним (кроме самого default.nix
) с переданными ему на вход аргументами и возвращает список оверлеев.
Теперь в директорию overlays
можно закидывать файлы с оверлеями, обернув их в лямбду, что принимает нужные парметры. Для примера сделаем overlays/fcitx5/default.nix
с таким содержимым:
{ pkgs, config, lib, ... }:
(self: super: {
rime-data = ./rime-data-flypy; # Кладем кастомный пакет в rime-data
fcitx5-rime = super.fcitx5-rime.override { rimeDataPkgs = [ ./rime-data-flypy ]; };
})
2
3
4
5
6
Пример выше оверрайдит пакет rime-data
на лежащу в директории с оверлеем кастомную версию и меняет rimeDataPkgs
у fcitx5-rime
на ранее положенный в rime-data
пакет.
Чтобы подгрузить овелеи, возвращаемые написанным overlays/default.nix
, добавляем следующее в любой NixOS-модуль:
{ config, pkgs, lib, ... } @ args:
{
# ...
nixpkgs.overlays = import /путь/до/директории/с/оверлеями;
# ...
}
2
3
4
5
6
7
8
9
Например, это можно сделать сразу в flake.nix
:
{
description = "NixOS configuration of Ryan Yin";
# ...
inputs = {
# ...
};
outputs = inputs@{ self, nixpkgs, ... }:
{
nixosConfigurations = {
nixos-test = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = inputs;
modules = [
./hosts/nixos-test
# описываем inline-модуль;
# то, что приходит на вход модулю, передается оверлеям
(args: { nixpkgs.overlays = import ./overlays args; })
# ...
];
};
};
};
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Такой подход позволяет упорядочить оверлеи, а так же сильно упрощает добавление новых и удаление более не нужных оверлеев. В данном примере директория overlays
выглядит слеюующим образом:
.
├── flake.lock
├── flake.nix
├── home
├── hosts
├── modules
├── ...
├── overlays
│ ├── default.nix # автоматически подтягивает оверлеи
│ └── fcitx5 # оверлей с fcitx5
│ ├── default.nix
│ ├── README.md
│ └── rime-data-flypy # кастомный rime-data
│ └── share
│ └── rime-data
│ ├── ...
└── README.md
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17