Jul 06, 2016

Пакетный менеджер Nix

См.также

http://nixos.org/nix/

Nix - пакетный менеджер, который устанавливает пакеты изолированно друг от друга. Изначально появился в процессе научной работы Eelco Dolstra и позже обрел огромную популярность и сторонников данной идеи, что в итоге сформировало очень активное сообщество, ссылки на которое можно найти здесь nixos.

Nix в отличии от других UNIX дистрибутивов устанавливает пакеты всегда в одно и то же место /nix/store/. Внутри каждого пакета создается необходимая структура директорий bin, etc, lib, и прочее. Пользователь видит это все у себя за счет симлинков, которые прописываются при установке, см. рисунок:

../../../_images/nix_fs.png

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

Отличительной особенностью nix, является то, что он не зависит от дистрибутива. Единственным требованием является поддержка POSIX потоков и C++ компилятор. Все пакеты из реп запускаются, без проблем, на любом Linux дистрибутиве и многие платформонезависимые пакеты работают в MacOS. Есть инструкции как установить nix в Cygwin под Windows. Я пользуюсь nix под CentOS6, CentOS7, Ubuntu, NixOS и это работает везде одинаково хорошо.

Из плюсов можно отметить:

  • везде одинаковый интерфейс, не нужно запоминать как работает yum, apt, apk, ...
  • одна репа для всех дистрибутивов, везде одинаковые версии программ
  • репа на гитхабе, это очень удобно (https://github.com/NixOS/nixpkgs)
  • изолированная установка, новый пакет не может сломать остальные
  • возможность установки нескольких версий одного пакета, например glibc
  • транзакционность - развитая модель откатки состояния
  • огромное количество пакетов, самых свежих версий
  • хранит все в одной директории /nix, не захламляет систему, удаляется одной командой rm -rf /nix

Из минусов:

  • чуть больший размер пакетов, из-за того что могут использоваться разные версии одной и той же зависимости в разных пакетах
  • сервисы и демоны устанавливаются в виде бинарников, прописывать их в автозапуск и систему инициализации придется вручную. Это не относится к NixOS

Установка

Установка крайне простая, делается одной командой:

$ curl https://nixos.org/nix/install | sh

Команды

NixOS удивительный проект с очень хорошей документацией и большим мега-активным сообществом (NixOS). Поэтому нет смысла дублировать документацию, опишу лишь некоторые команды в сравнении с пакетным менеджером apt.

Установка пакетов:

apt
$ sudo apt-get install firefox python vim
nix
$ nix-env -i firefox python vim

Удаление:

apt
$ sudo apt-get remove python
nix
$ nix-env -e python

Обновление реп:

apt
$ sudo apt-get update
nix
$ nix-channel --update

Обновление пакетов:

apt
$ sudo apt-get upgrade
nix
$ nix-env -u

Информация о пакете:

apt
$ apt-cache search vim
nix
$ nix-env -qaP | grep vim

Описание пакета:

apt
$ apt-cache show vim
nix
$ nix-env -qaP --description | grep vim

nix-shell

nix-shell создает изолированное окружение (наподобие virtualenv в питоне) и позволяет запускать в нем команды или выполнять nix скрипты.

Пример как создать окружение с nodejs, python3 и gnumake:

$ nix-shell -p nodejs python3 gnumake

После этого nodejs, python3 и gnumake появятся в нашем окружении. Выйти из окружения можно так-же как и из bash оболочки Ctrl + D или командой exit.

Понять что мы находимся в nix-shell сессии можно при помощи переменной окружения:

$ env | grep IN_NIX_SHELL
IN_NIX_SHELL=1

Я добавил отображение символа снежинки в PS1, если nix-shell сессия активна.

../../../_images/nix_shell.png

Очень удобно создавать окружение для скриптов через shebang:

shebang создает окружение для python2 и запускает в нем скрипт
 #! /usr/bin/env nix-shell
 #! nix-shell -i python -p python pythonPackages.prettytable

 import prettytable

 # Print a simple table.
 t = prettytable.PrettyTable(["N", "N^2"])
 for n in range(1, 10): t.add_row([n, n * n])
 print t
shebang создает окружение с утилитой cowsay и запускает в баше скрипт
 #! /usr/bin/env nix-shell
 #! nix-shell -i bash -p cowsay

 cowsay "Превед nix-shell!!!"

По умолчанию команда nix-shell ищет файл default.nix в текущей директории и пытается его выполнить, таким образом мы можем создавать для своих проектов своеобразное виртуальное окружение, просто положив этот файл в корень проекта и прописав в нем необходимые пакеты и правила сборки. Такой проект легко будет развернуть на любой системе. Отличной демонстрацией этого является проект RhodeCode (позволяет управлять кодом как GitLab, но при этом может использовать разные системы контроля версий git, hg, svn и интегрируется с разными треккерами задач вплоть до Trello), который можно развернуть у себя за 5 мин при помощи команды nix-shell (https://docs.rhodecode.com/RhodeCode-Enterprise/contributing/dev-setup.html).

Также nix-shell позволяет присваивать имена окружениям и запускать nix выражения, например что бы собрать приложение изолированно от общих установленных пакетов.

Более подробно, что такое язык nixexpr и как при помощи его собирать пакеты и даже ОС NixOS, я постараюсь описать в отдельной статье.

/home/user Окружение

Что бы Ubuntu знала о наших приложениях нужно прописать симлинк:

ln -s ${HOME}/.nix-profile/share/applications/ \
    ${HOME}/.local/share/applications/

Резюме

Пакетный менеджер Nix имеет огромное количество преимуществ, которые упрощают процессы администрирования, программирования, сборки и тестирования ПО. Теперь на разных Линуксах все работает одинаково! А в CentOS6 есть gcc6.


Comments

comments powered by Disqus