Библиотека сайта rus-linux.net
Nix – инструмент, помогающий выбраться из «ада зависимостей»
Оригинал: "Nix fixes dependency hell on all Linux distributions"Авторы: Pjotr Prins, Jeeva Suresh, Eelco Dolstra
Перевод: Юрий Овчаренко
Дата перевода: 25 января 2009 г.
Пакетный менеджер следующего поколения Nix, это инструмент, предлагающий простой подход для управления бинарными пакетами и пакетами на основе исходных кодов независимо от версии вашего дистрибутива, будь то Ubuntu, Debian, Suse, Fedora или Rad Hat. Более того, Nix не конфликтует со штатным пакетным менеджером вашего дистрибутива. В отличие от большинства пакетных менеджеров, Nix позволяет установить параллельно несколько версий одного и того же пакета, при этом избежать конфликтов и сохранить возможность откатов установленых обновлений. Это удобный инструмент для системного администрирования в условиях гетерогенной (неоднородной) среды а так же для разработчиков, пишущих ПО с поддержкой разных версий библиотек, компиляторов и интерпретаторов.
Зачем же нам нужен еще один пакетный менеджер? Потому что существующие недостаточно хорошо справляются со своими задачами в условиях постоянного обновления пакетов в системе. Рано или поздно пользователь сталкивается с проблемой неудовлетворенных зависимостей. По этой причине в частности, многие пользователи предпочитают отказаться от обновления своей системы с выходом её новой версии, предпочитая переустановить систему «с нуля». Nix делает процесс обновления безопаснее, попросту не позволяет перезаписывать уже установленные пакеты и таким образом предоставляет возможность продолжать пользоваться предыдущей версией программы параллельно с установленной новой версией, а в случае необходимости легко осуществить откат.
Проект Nix родился в Университете Утрехта в Нидерландах, название происходит от голландского «ничто».
Проблема: деструктивные обновления, несовместимости версий, разнородное окружение
Все популярные пакетные менеджеры, включая APT, RPM и систему портов FreeBSD, подвержены проблеме деструктивных обновлений пакетов ПО. Когда вы производите обновление, будь то апдейт одного пакета или системы целиком, пакетный менеджер перезаписывает установленные файлы их новыми версиями. До тех пор, пока обратная совместимость между версиями файлов сохраняется, проблем не возникает, но к сожалению в реальности пакеты не обладают свойством обратной совместимости.
Предположим к примеру, что вы решили обновить браузер Firefox и ваш пакетный менеджер решил, что необходимо так же обновить библиотеки GTK. Если новая версия GTK не имеет достаточной обратной совместимости, вы рискуете столкнуться с тем, что некоторые установленные ранее пакеты перестанут работать. В Windows-системах подобная проблема называется «адом dll», в мире UNIX эту проблему называют «адом зависимостей» (dependency hell) и здесь она является много более актуальной, поскольку программы в *nix системах как правило имеют много внешних зависимостей
Деструктивные обновления также затрудняют отмену или «откат» произведенных в системе обновлений, до тех пор, пока вы или ваш пакетный менеджер не позаботились о резервном копировании файлов, перезаписываемых в процесе установки обновлений.
Наконец во время того, как менеджер занят установкой новых версий пакетов и перезаписыванием существующих файлов, система находится в нестабильном состоянии, в котором не гарантируется нормальная работа установленных программ. Попробуйте выключить питание компьютера во время очередного обновления вашей системы и посмотрите, сможет ли после этого система загрузиться! (Прим. переводчика: лучше поверьте автору на слово и не проверяйте ;))
Обычно обновление пакета делает недоступным установленный ранее пакет предыдущей версии. Иногда однако менеджеры пакетов дают возможность установить новую версию параллельно со старой, скажем пакеты gcc-3.4 и gcc-4.3. Однако это работает только в том случае, если менеджер позаботился о том, чтобы разные версии пакетов были установлены в разных местах. Как быть если вы хотите попробовать gcc-4.0.3, не повредив при этом установленную версию компилятора? Или вам необходимо протестировать ПО, используя различные версии компиляторов, библиотек, интерпретаторов и их комбинаций? Как вам посмотреть на новую бета-версию любимой программы, не рискуя при этом уже установленной более ранней версией?
Далее имеется проблема поддержки ПО в разных дистрибутивах. Разработчики и системные администраторы не могут знать, какая комбинация из ядра, библиотек и пакетов установлена в системе пользователя. Когда пользователь при инсталляции пакета сталкивается с ошибкой отсутствия нужной библиотеки, вы можете посоветовать установить её, однако вы не тестировали это ПО в условиях такой же комбинации зависимостей, как на машине данного пользователя, следовательно и не можете быть уверены, что все будет работать как надо.
Можно также порекомендовать пользователю собрать програму из исходников, но у него может не оказаться подходящих версий компилятора и библиотек. Даже если вы работаете в организации занимающейся стандартизацией данного конкретного дистрибутива, может оказаться что у пользователя устаревшие несовместимые версии библиотек.
Существующие пакетные менеджеры неплохо справляются с поддержкой стабильных версий систем, поскольку они опираются на длительный период разработки и тестирования множеством людей. Однако, когда пользователям необходимо самое свежее обновление програмного обеспечения, скажем по причине найденной ошибки или отсутствия необходимого функционала, они обращаются к тестовым и нестабильным версиям пакетов, которые в свою очередь требуют обновления зависимых пакетов, что ведет к потенциальной нестабильности этих компонентов и всей системы в целом.
Nix внедряет более гибкий подход, позволяющий устанавливать и параллельно использовать разные версии одной и той же программы. Вместо того, чтобы устанавливать программы в системые директории типа /usr, Nix использует отдельные директории для устанавливаемых пакетов в /nix/store. В директории верхнего уровня каждого пакета находится его криптографический хэш, который служит уникальным идентификатором пакета, хранящем информацию о версии и зависимостях. Таким образом разные версии пакета не создают конфликтов между собой и своими зависимостями, так что пользователь в любой момент может произвести строго направленное обновление или отмену обновления компонента.
Начинаем работу с Nix
По иронии судьбы, наилучший способ начать использовать Nix, это обычная сборка из исходников, посредством стандартных комманд ./configure ; make ; make install, выполненых от суперпользователя. Это справедливо для всех систем, включая MacOS X и BSD. Вам понадобится стандартное окружение GNU g++ и установленный curl. Когда установка завершена, Nix в этих инструментах больше не нуждается. Устанавливаемые пакеты и служебная информация хранятся в директории /nix, так что позаботьтесь о наличии достаточного дискового пространства. Если на устройстве, где примонтируется корневая файловая система, недостаточно места, используйте отдельный раздел для /nix, либо используйте возможности bind-mount для монтирования директории /nix на устройство, где имеется свободные 5-50 Гб. Вам так же потребуется добавить путь к usr/local/etc/profile.d/nix.sh в ваш файл bashrc (это установит необходимые для Nix переменные окружения).
Когда Nix собран и установлен, можно начинать устанавливать программы с его помощью. Вы можете получить нужные Nix-пакеты (nixpkgs) скачав их с веб-сайта NIX или подключившись к их Subversion-репозиторию. Однако есть более простой способ, это подписка на канал nixpkg, который создан для автоматического информирования пользователей о новых nix-пакетах:
Пакет nixpkg состоит из набора выражений на спецязыке nix, описывающих систему сборки входящих в него пакетов, подобно системе ebuild в Gentoo. Nix преимущественно является менеджером пакетов, собираемых их исходных кодов (подобно Portage), однако он автоматически скачает и установит бинарные пакеты, если информация об их наличии найдется в его хэше. На канале nixpkg находится информация о большом количестве прекомпилированных бинарных пакетов, что позволяет существенно сократить время, затрачиваемое на установку.
nix-env -qa '*'или, к примеру, список пакетов, содержащих в названии «firefox» :
nix-env -qa firefox.В результате вы получите список подобный этому:
firefox-2.0.0.17 firefox-2.0.0.17-with-plugins firefox-3.0.4 firefox-3.0.4-with-plugins
Можно добавить опцию -s чтобы посмотреть список прекомпилированных бинарных пакетов. Заглавная S в списке указывает на то, что можно скачать бинарную версию пакета.
--S firefox-2.0.0.17 --- firefox-2.0.0.17-with-plugins --S firefox-3.0.4 --- firefox-3.0.4-with-plugins
Установка пакетов с зависимостями
Чтобы убедиться в возможностях Nix, давайте представим, что мы хотим установить Firefox 2 с набором плагинов, удовлетворив при этом все зависимости и не перезаписав никаких из существующих в системе файлов. Введите команду nix-env -i firefox-2.0.0.17-with-plugins, Nix скачает и скомпилирует все необходимые пакеты. Несмотря на то, что firefox-2.0.0.17-with-plugins недоступен в виде бинарного пакета, большинство пакетов, от которых он зависит, доступны. Nix скачает и установит бинарные пакеты, если это возможно, в остальных случаях скомпилирует их их исходных кодов. У программы Firefox много зависимостей, от библиотек GNU C до GTK. Вероятно, большинство необходимого уже есть в вашем дистрибутиве, однако Nix скачает и установит собственные копии, чтобы можно было быть уверенным, что в системе имеются именно необходимые версии и отсутствуют конфликты между ними. В конце концов, в наши дни вполне можно позволить себе пожертвовать дисковым пространством ради стабильной и предсказуемой системы.
После установки необходимых компонентов можно запустить Firefox (возможно вам еще понадобиться задать для переменной FONTCONFIG_FILE значение /etc/fonts/fonts.conf чтобы firefox мог использовать установленные в системе шрифты).
nix-env -i firefox-3.0.4-with-pluginsили, если вы хотите получить последнюю доступную версию,
nix-env -u firefoxТеперь у вас установлен Firefox 3, но при этом доступен также и Firefox 2, они автоматически разнесены по разным директориям:
/nix/store/vskr06rlblihz22...-firefox-2.0.0.17-with-plugins /nix/store/w1i05b7s30zqz...-firefox-3.0.4-with-plugins
Вы так же можете продолжать пользоваться ранее установленными в вашей системе версиями пакетов. Пакеты, установленные посредством Nix, являются дополнительными и независимыми.
Профили
Установленные программы можно вызывать, используя полный путь к ним в системе, что весьма неудобно, или посредством добавления путей их установки в общесистемный список путей поиска. Поэтому nix-env автоматически создает дерево символьных ссылок к установленым программам. Чтобы эти ссылки работали, необходимо добавить в переменную $PATH что-то вроде ~/.nix-profile/bin, это путь, указывающий на дерево ссылок. Тем самым обеспечивается возможность обновления отдельных пакетов и отмены таких обновлений, Nix создает дерево символьных ссылок для каждого устанавливаемого пакета, затем прописывает путь к нему в ~/.nix-profile, чтобы сделать их доступными в системе.
nix-env --profile my-firefox-test -i firefox-3.0.4-with-pluginsпосле чего запустить ./my-firefox-test/bin/firefox (этот файл является символьной ссылкой на Firefox 3 в /nix/store). Это не затронет вашего «обычного» Firefox, установленного в ~/.nix-profile/bin.
Откаты
Так как установка Firefox 3 не затронула установленного ранее Firefox 2, отменить изменения в системе не составляет труда. Все что вам нужно чтобы вернуться к Firefox второй версии, это ввести nix-env —rollback. Конечно, в конце концов вы захотите удалить старые версии пакетов, которые более вам не нужны. Чтобы удалить пакет без возможности последующего отката, введите nix-collect-garbage -d, в нашем случае эта команда удалит firefox 2 и все его зависимые пакеты, которые более не используются.
Создание собственных пакетов
Наконец, Nix имеет свой собственный специфический язык для создания описаний к пакетам. Это функциональный и при этом ясный язык прекрасный инструмент для создания и поддержки пакетов и их зависимостей. Пример описания пакета для PHP с зависимостями выглядит примерно так:
Это выражение на языке Nix требует удовлетворения зависимости от пакета libxml2 и предоставляет возможность выбора интерфейса для SQL при инсталляции.Nix выражения позволяют использовать большой набор комманд для описания пакетов, что позволяет добиться компактности и понятности. Во время установки список пакетов и зависимостей отделен от общесистемного, так что путаницы с зависимостями не возникает и все зависимости обязательно будут удовлетворены.
Для более гибкого управления пакетами имеется возможность передать опции конфигуратору пакетов. К примеру можно установить пакет с поддержкой графического интерфейса для настольной системы и без поддержки для сервера. Nix позволяет так же установить урезанные версии программ и документацию. Более сложные примеры можно посмотреть на package source tree.
Заключение
Используя Nix вы получаете возможность иметь в качестве основы цельный и стабильный дистрибутив, наподобие Debian stable или Red Hat Enterprise Linux, но при этом при не отказывать себе в возможности попробовать самое свежее ПО, не представленное в репозиториях вашего дистрибутива, причем без риска нарушить стабильность системы, всегда имея возможность отмены внесенных изменений. С Nix вы забудете, что такое ад зависимостей, и получите намного более предсказуемую систему управления програмами.