Добро пожаловать на вторую пилюлю Nix.
В первой пилюле мы коротко рассказывали про Nix.

Теперь мы установим Nix на нашу систему и разберёмся, что изменилось после установки.
Если вы используте NixOS, Nix у вас уже установлен, так что вы можете переходить к следующей пилюле.

За инструкциями по установке, пожалуйста, обратитесь к разделу Установка Nix Справочного руководства Nix.

(Адрес этой статьи на официальном сайте перевода).

Установка

Эти статьи --- не руководство по использованию Nix.
Не погружаясь в формальности, мы прогуляемся по системе Nix, чтобы разобраться, как она устроена.

Первая важная вещь: порождения в хранилище Nix ссылаются на другие порождения, которые также находятся в хранилище Nix.
Они не используют libc из нашей системы или откуда-то ещё.
В хранилище находятся все необходимые библиотеки, которые могут потребоваться, чтобы запустить любой конкретный пакет.

?
При многопользовательской установке (такая как раз применяется в NixOS), хранилищем владеет root, а многочисленные пользователи могут устанавливать или собирать софт при помощи демона Nix.
Больше о многопользовательской установке вы можете прочитать здесь: https://nixos.org/manual/nix/stable/installation/installing-binary.html#multi-user-installation.

С чего начинается хранилище в Nix

Взглянем, что печатает команда установки:

    copying Nix to /nix/store..........................

Речь идёт о каталоге /nix/store, который мы обсуждали в первой статье.
Туда мы копируем всё, что необходимо для запуска системы Nix.
Вы можете заметить bash, утилиты ядра, компилятор C, библиотеки Perl, sqlite и сам Nix с его утилитами и libnix.

Возможно, вы заметили, что /nix/store может содержать не только каталоги, но и файлы. У них такой же формат имени /hash-name.

База данных Nix

Сразу после наполнения хранилища, процесс установки инициализирует базу данных:

    initialising Nix database...

Да, в Nix есть база данных.
Она находится в /nix/var/nix/db.
Это база данных sqlite, которая хранит зависимости между порождениями.

Схема очень простая: есть таблица корректных путей, где каждому пути сопоставлен целый автоинкрементный ключ.

Далее, есть таблица зависимостей, где записано, от каких путей зависит каждый новый путь.

Вы можете исследовать эту базу, установив sqlite (nix-env -iA sqlite -f '<nixpkgs>') и выполнив команду sqlite3 /nix/var/nix/db/db.sqlite.

?

Сразу после установки Nix не забудьте закрыть и заново открыть терминалы, чтобы обновить настройки командной строки.

?

Никогда не изменяйте /nix/store вручную, или хранилище больше не будет синхронизировано в базой данных sqlite.
Ну, или вы на самом деле знаете, что делаете.

Первый профиль

Теперь, когда установка завершена, давайте познакомимся с важным понятием профиля:

creating /home/nix/.nix-profile
installing 'nix-2.1.3'
building path(s) `/nix/store/a7p1w3z2h8pl00ywvw6icr3g5l9vm5r7-user-environment'
created 7 symlinks in user environment

Профиль в Nix --- общая и удобная концепция для отката изменений.
Профили используются для объединения компонентов, размещённых по разным путям, в один путь.
Более того, профили могут состоять из нескольких "поколений": они версионируются.
Когда вы меняете профиль, создаётся новое поколение.

Поколения можно переключать и отктывать атомарно, что делает управление изменениями в вашей системе особенно удобным.

Рассмотрим наш профиль подробнее:

$ ls -l ~/.nix-profile/
bin -> /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-nix-2.1.3/bin
[...]
manifest.nix -> /nix/store/q8b5238akq07lj9gfb3qb5ycq4dxxiwm-env-manifest.nix
[...]
share -> /nix/store/ig31y9gfpp8pf3szdd7d4sf29zr7igbr-nix-2.1.3/share

Порождение nix-2.1.3 в хранилище Nix --- это сам Nix вместе с исполняемыми файлами и библиотеками.
Процесс "установки" порождения в профиль, в сущности воспроизводит дерево nix-2.1.3 из хранилища с помощью символических ссылок.

Содержимое этого профиля особенное, поскольку только одна программа установлена в наш профиль, таким образом, каталог bin содержит именно неё (это сам Nix).

Но то, что он содержит --- всего лишь последнее поколение нашего профиля.
Фактически, ~/.nix-profile --- символическая ссылка на /nix/var/nix/profiles/default.

Которая, в свою очередь, тоже является символической ссылкой на default-1-link в том же каталоге.
Да, это значит, что речь идёт о первом покололении профиля default.

В конечном итоге, default-1-link --- символическая ссылка на порождение "user-environment", которое печаталось на экране в процесс установки.

О файле manifest.nix мы подробнее поговорим в следующей статье.

Выражения Nixpkgs

Больше вывода от программы установки:

downloading Nix expressions from `http://releases.nixos.org/nixpkgs/nixpkgs-14.10pre46060.a1a2851/nixexprs.tar.xz'...
unpacking channels...
created 2 symlinks in user environment
modifying /home/nix/.profile...

Выражения Nix написаны на языке Nix, они описывают пакеты и то, как их собирать.
Nixpkgs — это репозиторий, содержащий все выражения: https://github.com/NixOS/nixpkgs.

Установщик скачал описания пакетов, начиная с коммита a1a2851.

Второй профиль, с которым мы столкнулись --- это профиль каналов.
~/.nix-defexpr/channels ссылается на /nix/var/nix/profiles/per-user/nix/channels, который в свою очередь ссылается на channels-1-link, который ссылается на каталог в хранилище со скачанными выражениями Nix.

Каналы --- это множество пакетов и выражений, доступных для скачивания.
Подобно стабильным и нестабильным репозиториям в Debian, в Nix есть есть стабильные и нестабильные каналы.
В этой установке, мы отслеживаем nixpkgs-unstable.

Пока не беспокойтесь о выражениях Nix, мы разберёмся с ними позже.

В конечном итоге, для большего удобства, установщик изменил ~/.profile, чтобы вы попадали в окружение Nix автоматически.
Что делает ~/.nix-profile/etc/profile.d/nix.sh на самом деле — просто добавляет ~/.nix-profile/bin в PATH и ~/.nix-defexpr/channels/nixpkgs в NIX_PATH.
Переменную NIX_PATH мы обсудим позже.

Прочитайте nix.sh, он короткий.

Вопросы и ответы: можно ли заменить /nix на что-то другое?

Да, можно, но есть веская причина использовать именно каталог /nix вместо любого другого.
Все порождения зависят от других порождений, используя при этом абсолютные пути.
В первой статье мы видели, что bash ссылается на glibc по конкретному абсолютному пути внутри /nix/store.

Убедитесь сами, и не волнуйтесь, если увидите множество порождений bash:

$ ldd /nix/store/*bash*/bin/bash
[...]

Размещая хранилище в /nix, мы можем напрямую использовать бинарные образы с nixos.org (точно также, как и пакеты с зеркал Debian), в противном случае:

  • glibc будет установлен в /foo/store

  • После этого bash будет указывать на glibc в /foo/store вместо /nix/store

  • В результате мы не сможем использовать бинарный образ, так как нам нужен другой bash, и мы вынуждены перекомпилировать вообще всё.

Помимо прочего, /nix — осмысленное место для хранилища.

Заключение

Мы установили Nix в нашу систему. Он полностью изолирован и принадлежит пользователю nix, а мы продолжаем знакомиться с особенностями новой системы.

Мы познакомились с новыми концепциями, такими как профили и каналы.
В частности, с помощью профилей мы научились управлять поколениями составных пакетов, а с помощью каналов --- загружать бинарные образы с nixos.org.

Программа установки помещает всё в каталог /nix, создавая несколько символических ссылок в домашнем каталоге пользователя Nix.

Я надеюсь, что объяснил все детали, чтобы вы не думали, что здесь всё дело в волшебстве.
Всё сводится к тому, что компоненты находятся в хранилище и ссылаются друг на друга через символические ссылок.

В следующей пилюле

...мы погрузимся в окружение Nix и научимся взаимодействовать с хранилищем.

Комментарии (4)


  1. volaand
    04.04.2024 08:06
    +1

    На сегодняшний день были бы актуальны теже пилюли только с хлопьями(flakes)...


    1. markshevchenko Автор
      04.04.2024 08:06

      Давайте так. Этот цикл переведу, за ним можно и flakes.


  1. eyeDM
    04.04.2024 08:06

    А как организуется маппинг /etc? Например, я хочу установить несколько версий одного пакета, у которых базовые конфиги из /etc/pkgname несовместимы между собой... Всё в /nix/ кидается, по типу chroot?


    1. markshevchenko Автор
      04.04.2024 08:06

      Обычно пакеты адаптируют к подходу Nix. Вы можете зайти сюда: https://search.nixos.org/packages и поискать там нужный пакет. Если он есть, то он адаптирован для работы в Nix. Конечно, конфиги не складывают в /etc/pkgname. Можно для конкретного проекта написать скрипт на языке Nix, который создаст конфиг, и этот конфиг будет доступен через переменную окружения. В других проектах будут свои скрипты, которые будут создавать своё окружение.