Fork me on GitHub
17/7/2010

Мельком о Buildout

Buildout изначально создавался в Zope-коммунити как средство для управления окружением из десятков «яиц». С подачи Джейкоба Каплан-Мосса этот инструмент дошел и до Django.

Я долго избегал использовать Buildout… было пару «подходов» к нему, и всё никак не удавалось его толком рассмотреть.

Давайте посмотрим, какие проблемы пытается решить Buildout и как у него это получается.

Первая проблема — это изолированность окружения. Очень часто возникает ситуация, когда разные приложения используют разные версии библиотек.

Эту проблему можно решить по-разному, например, если это не яйца, а обычные Python-пакеты, то можно просто собрать необходимый набор библиотек в отдельный каталог libs рядом с приложением. Затем, переопределив переменную окружения PYTHONPATH или из Py-кода добавив libs в sys.path, получить возможность импорта нужных библиотек.

Чуть по-другому обстоят дела, если нужны возможности яиц (скрипты, плагины). В этом случае простым каталогом не обойтись. Здесь поможет virtualenv от Яна Бикинга. Virtualenv отличный инструмент и он действительно решает проблему изолированных окружений. Я его использую для тестирования зависимостей и установки пакетов «на посмотреть». Что мне не нравится в virtualenv, так это: а) Измененное поведение песочницы при модификации PYTHONPATH/sys.path по сравнению со «стандартным» интерпретатором. Это несколько обескураживает, хотя заставляет более аккуратно работать с пакетами. б) Переключение окружения между состояниями активировано/деактивировано. По мне так намного более правильно использовать явные пути. в) Абсолютные пути в окружении. Как следствие, окружение просто так не перенесешь.

Buildout предлагает комбинирование этих способов: вы явно описываете конфигурацию песочницы, а buildout переопределяет sys.path нужным образом, плюс раздельно хранит и устанавливает яйца. В отличии от virtualenv, песочница buildout не является полностью изолированной от общего окружения. Проще говоря, virtualenv гарантирует полноту зависимостей пакета, а buildout — нет. С другой стороны, никто не мешает сделать вложенную песочницу: сделать окружение virtualenv, а внутри него — buildout.

Вторая проблема, которую пытается решить buildout — это воспроизводимость окружения. Крайне желательно, чтобы окружение на различных хостах, дистрибутивах и ОС было максимально единообразно и ручные действия сводились бы к минимуму. Это сильно облегчает деплой, тестирование и значительно упрощает ввод в команду нового человека.

Эту проблему можно решить, если добавить окружение в систему контроля версий. Но это работает, если а) у вас не яйца, а просто пакеты б) у вас только pure Python модули в окружении. Во всех остальных случаях приходится что-то придумывать. Хорошо, если все зависимости доступны как яйца, в этом случае можно взять комбинацию virtualenv+pip/easy_install и получать базовое окружение. Но для воспроизводимости нужно, чтобы вы контролировали еще и сервер, с которого pip/easy_install скачивает пакеты, иначе вы зависите от PyPI, выпуска новых библиотек и проч.

Buildout помогает ровно тем, что всё это вы можете указать в конфигурационном файле и забыть об опциях ;)

Третья проблема, на которую нацелен Buildout — это переключение конфигов. Очень часто в dev/test/stage/production режимах отличаются параметры. Возникает желание упростить процесс переключения между режимами конфигов. Если говорить о Django, то альтернативы сводятся к импорту общей части и явному указанию локального конфига, или использование общей части и перезапись локальными конфигами (см. например Byteflow).

Buildout делает это чуть более аккуратно и явно, позволяя «наследоваться» от конфигов, расширять их и проч.

По сути, buildout:

  • предоставляет песочницу для пакетов
  • даёт гибкий контроль над версиями пакетов
  • позволяет переключать относительно быстро переключать наборы конфигов

Buildout не является серебрянной пулей, и на мой взгляд, обладает недостатками:

  • необходимость Internet. По факту, Buildout без Internet практически не работоспособен. Да, у него есть оффлайн-режим, но у меня не получилось построить окружение «с нуля», имея на диске все необходимые «яйца» и пакеты.
  • переусложненные конфиги. Если посмотреть на Buildout-конфиги Plone, то становится несколько не по себе: конфигурационные файлы на несколько экранов с хитрыми связями между секциями, наследованием и проч.
  • отсутствие единообразия в Buildout-рецептах. Кто в лес, кто по дрова. Есть рецепты даже для компилирования MySQL и PostrgeSQL, однако нет ничего для управления зависимостей rpm/deb пакетов.

В целом, после небольшого опыта использования Buildout, у меня возникло ощущение, подобное привкусу от «яиц»: инструмент нацелен на правильную область, он закрывает важную часть проблем, но не делает всё «правильно», нет прозрачности и прямолинейности. Я жду, пока появится преемник buildout, каким для easy_install стал pip. А пока, использую buildout, но аккуратно и без фанатизма :)

Комментарии

Все статьи