Персональные инструменты
Вы здесь: Главная Документация Руководства Управление проектом с помощью buildout

Управление проектом с помощью buildout

ПРИМЕЧАНИЕ: Это вид всех страниц руководства удобный для печати. Постраничное представление доступно здесь, если Вам так удобнее.

Узнайте о яйцах, setuptools и управлении зависимостями, а также как использовать buildout для конфигурации среды разработки. Оригинал документа http://plone.org/documentation/manual/developer-manual/managing-projects-with-buildout

1. Введение

Или что случилось с старым добрым инстансом

В этом руководстве рассказывается, как установить Plone 3 в виде buildout, и как использовать buildout для работы над программными продуктами,  расширяющими Plone. Buildout - это автономная среда, которая позволяет управлять зависимостями (включая Zope и Plone и любые другие нужные вам сторонние продукты или библиотеки) и пользовательским кодом для вашего проекта. Даже если вы не планируете писать свой код, buildout подход - это простой, надежный и хорошо протестированный способ установки Plone.  Начиная с Plone 3.2, все инсталляторы основаны на buildout.

До Plone 3 большинство разработчиков и пользователей, не использовавших GUI инсталляторы, должны были поднимать Zope инстанс и копировать продукты в папку Products для того, чтобы установить Plone. К сожалению, у этого подхода есть ряд проблем:

  • Zope инстанс старого образца не очень хорошо подходил для управления пакетами распространяемые в виде егг-пакетов. Много новых продуктов в Plone 3, так же как и сторонние продукты,  уже распространяются как егг-пакеты и будут это делать в дальнейшем. 
  • Не имея доступ к метаданным, хранимым в eгг-пакетах, разработчики предпочитали объединять свой код в один монолитный продукт вместо того, что организовывать его в виде нескольких небольших пакетов, которые можно повторно использовать в других проектах и даже вне Zope
  • Для установки продуктов в разных средах приходилось каждый раз повторять одни и те же обременительные действия

По мере того, как eggs играли все более важную роль, разработчики начали использовать более подходящие для управления своим кодом инструменты. zc.buildout, упоминаемый в дальнейшим как "buildout", только один из них. Это руководство показывает как использовать buildout как и для разработки так и для развертывания программного продукта.

Детальная документация по buildout, созданному Jim Fulton из Zope Corporation,  доступна на http://buildout.org/

 

2. Пакеты, продукты и яйца

Посмотрим на концепцию глубже

Теминология

Прежде всего необходимо познакомиться с определениями:

  • Software home (домашняя директория Zope) - директория установки Zope ($SOFTWARE_HOME)
  • Zope instance (экземпляр Zope, инстанс) - процесс операционной системы, который обслуживает HTTP взаимодействие с базой данных Zope (ZODB). Также код на python и конфигурационные файлы необходимые для выполнения этого процесса.
    Одна установка Zope может содержать несколько инстансов. Используйте рецепт buildout plone.recipe.zope2instance, чтобы создать новый экземпляр Zope в buildout окружении. Несколько инстансов могут использовать данные из одного файла Data.fs, используя ZEO сервер.
  • Python path (python путь)  - порядок и место, в котором python-интерпретатор  будет искать модули. В python доступен через sys.path. При выполнении Zope этот python path обычно включает глобальные python модули, составляющие стандартную библиотеку, директорию site-packages, где установлены дополнительные глобальные модули и пакеты, домашнюю директорию Zope и директорию lib/python внутри домашней директории инстанса. Python скрипты могут включать дополнительные пути в эту переменную во время выполнения. Эта возможность используется zc.buildout.
  • Python package (python пакет) - общий термин обозначающий, распространяемые Python  модули. В общем случае это папка, в которой есть файл __init__.py и другой код на python.
  • Zope product (zope продукт) - особый тип пакетов Python используемых для расширения функциональности Zope. В старых версиях Zope все продукты были папками  в директории Products, и они должны были иметь имя начинающееся c Products. Например, продукт CMFPlone - ядро Plone, известен в Python как Products.CMFPlone
  • Python egg (python егг-пакет, яйцо) - способ упаковки и распространения модуля Python. Каждый егг-пакет содержит файл setup.py c метаданными (такими как имя и емейл автора и сведения о  лицензии) и информацию о зависимостях. Механизм eggs обеспечивается setuptools, которая способна автоматически находить и загружать зависимости для устанавливаемых пакетов. Возможно также использовать разные версии одних и тех же пакетов-зависимостей для разных модулей.  Егг-пакеты поддерживают также точки входа,  для обеспечения механизма плагинов. Больше информации доступно на сайте PEAK.
  • The Python Package Index (индекс python-пакетов)- это база из тысяч Python пакетов для загрузки. Она доступна в виде веб-сайта. Но что более важно инструменты на основе setuptools (buildout и easy_install) могут выполнять запросы к этой базе и устанавливать егг-пакеты автоматически. Также она называется Cheese Shop или PyPI
  • easy_install - инструмент с интерфейсом командной строки для автоматического поиска и установки пакетов в Python среду. Cкрипт easy_install - часть пакета setuptools, который используется PyPI в качестве источника пакетов.
  • Namespace package (пространство имен пакета) - особенность  setuptools, которая делает возможным распространение многочисленных отдельных пакетов, разделяющих единое пространство имен верхнего уровня. Например, пакеты plone.theme и  plone.portlets разделяют пространство имен "plone", но они распространяются как отдельные егг-пакеты. При установке исходный код каждого пакета находится в своей отдельной директории (или возможно в виде архива этой директории).  Благодаря пространству имен отпадает необходимость поставлять один гигантский пакет plone, в корне которого содержаться все возможные пакеты, например plone/theme и plone/portlets. 

 

Магия пространства имен Products

Каждый раз при старте когда Zope находит продукт, он создает запись в Control_Panel/Products в корне ZMI и выполняет метод intialize(), который находится в файле __init__.py в корневой директории продукта. Не каждый пакет в Plone  должен быть продуктом, но это требуется для пакетов, которые:

- содержат профиль GenericSetup

- содержать скины, которые должны быть установлены как слои  в portal_skins (для Zope 3 представлений браузера это  не требуется)

Самый простой способ создания продукта это использование  Paster/ZopeSkel с шаблоном basic_namespace:

$ paster create -t basic_namespace Products.myproduct
Selected and implied templates:
  ZopeSkel#basic_namespace  A project with a namespace package

Variables:
  egg:      Products.myproduct
  package:  productsmyproduct
  project:  Products.myproduct
Enter namespace_package (Namespace package (like plone)) ['plone']: Products
Enter package (The package contained namespace package (like example)) ['example']: myproduct
... accept defaults to end

Если вы используете buildout, создайте свой пакет в директории src и добавьте ссылку на него в секциих develop и instance/eggs в buildout.cfg:

develop =
    src/Products.myproduct
...
[instance]
...
eggs =
    ${buildout:eggs}
    ${plone:eggs}
    Products.myproduct

Запустите bin/buildout и у вас будет готовый к разработки продукт в директории src.

Возможно использовать пакеты вне пространство  имен Products и одноименной директории. Много разработчиков предпочитают этот подход, для них неудобно хранить все в едином, "плоском" пространстве имен.

Для этого необходимы дополнительные шаги. До Zope 2.10.4 это также необходимо для продуктов в пространстве имен Products.

Мы должны добавить следующую директиву в configure.zcml пакета: 

<configure 
    xmlns="http://namespaces.zope.org/zope"
    xmlns:five="http://namespaces.zope.org/five">

  <five:registerPackage package="." initialize=".initialize" />

</configure>

Далее, важна понимать, что пакеты вне пространства имен Products не определяются автоматически при старте Zope. Если они содержат файлы configure.zcml (для большинства пакетов это так), они должны быть явно подключены из других мест. Это может быть:

- configure.zcml другого пакета

- site.zcml, корень всех ZCML файлов,  который находится в директории  etc в корневом каталоге инстанса

- ZCML слаг, однострочный файл в etc/package-includes директории инстанса, с именем вида my.package-configure.zcml

Во всех случаях, синтаксис для подключения пакета один и тот же:

 

<include package="my.package" file="configure.zcml" />

Если у вас есть meta.zcml или overrides.zcml файлы, вы также можете добавить директивы <include /> для них. Если вы используете слаги, их имена должны быть соответствующие, например, my.package-meta.zcml или my.package-overrides.zcml. Слаг не может  содержать больше  одной строки.

Далее в руководстве, мы покажем как buildout может управлять слагами автоматически.

 

 

 

3. Предварительные условия

Несколько вещей которые нужно сделать перед началом

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

Начиная с Plone 3.2, все Plone инсталляторы основаны на buildout. Вы можете получить последнюю версию инсталлятора  и установить Plone на основе buildout не выполняя следующие шаги. Однако, эти шаги необходимы,  если вы хотите создать buildout вручную с помощью ZopeSkel

Сперва, нужен подходящий Python интерпретатор. Если у вас его нет, то:
  • Установите Python 2.4 для вашей платформы и добавьте его в системную переменную  PATH. Самый простой способ проверки какой python у вас это выполнить python -V в командной строке. Убедитесь, что вы используете Python 2.4, а не 2.5, так как Plone не поддерживает версию 2.5 и выше. Может быть вам понадобиться набирать python2.4 вместо просто python при выполнении некоторых ниже перечисленных команд.
  • Если вы установили Python используя менеджер пакетов вашей ОС (например, RPM), убедитесь, что также установлен пакет разработчика (python-devel). Он включает заголовочные файлы (header files),  которые мы будем использовать позже для компиляции Zope.  Если вы установили python из исходников или использовали Windows инсталлятор, то они уже у вас есть.
  • Установите PIL (Python Imaging Library)
  • Установите setuptools. Если вы используете Linux, в поставку которого не входит этот пакет, загрузите ez_setup.py и выполните следующее:
    $ python ez_setup.py

    С помощью этой команды вы загрузите и установите setuptools и скрипт easy_install. Посмотрите на вывод в консоле, чтобы понять, где установлен easy_install. Если это место не в PATH, вы должны также добавить эту директорию в path.

Наконец, используйте easy_install, чтобы получить ZopeSkel, коллекцию шаблонов для Zope/Plone разработки:

$ easy_install -U ZopeSkel

Это установит PasteScript и другие зависимости.

Замечание для пользователей Linux: Если вы устанавливаете setuptools и ZopeSkel на всю систему и не используете virtualenv, вы возможно должны стать супер пользователем или использовать sudo. Помните, что скрипт сборки (команда bin/buildout, с которой вы познакомитесь позже в этом руководстве) никогда не должен запускаться пользователем root. Если вы никак не можете избежать этого, поменяйте владельца созданных файлов (chown -R), чтобы они были доступны на чтение непривилегированному пользователю, от чего имени запускается Zope инстанс.

Если вы добавили директорию скриптов Python в PATH, то вы можете запустить команду paster. Протестируйте ее так:

$ paster create --list-templates
Available templates:
  basic_namespace:          A project with a namespace package
  basic_package:            A basic setuptools-enabled package
  basic_zope:               A Zope project
  nested_namespace:         A project with two nested namespaces.
  plone:                    A Plone project
  plone2.5_theme:           A Theme for Plone 2.5
  plone2_theme:             A Theme for Plone 2.1 & Plone 2.5
  plone3_buildout:          A buildout for Plone 3 projects
  plone3_theme:             A Theme for Plone 3.0
  plone_app:                A Plone App project

Текст вывода команды может слегка отличаться, проверьте, что есть как минимум шаблоны plone3_buildout  и plone.

Дополнительные шаги для пользователей Windows

Если вы работает под Windows, вы должны сделать еще кое-что.

Во-первых, загрузите и установите Python Win32 расширения для версии 2.4. Если вы собираетесь самостоятельно компилировать Zope, вместо использования инсталлятора или вам нужно компилировать пакет с C расширениями, то вам понадобится компилятор mingw32. Выберите как минимум модули base и make в процессе установки. По умолчанию, компилятор устанавливается в C:\MingW32. Внутри директории установки будет директория bin, например, C:\MingW32\bin. Добавьте ее в PATH. Наконец, вы должны настроить Python пакет distutils для использования с mingw32. Содайте файл disutils.cfg в директории C:\Python24\Lib\distutils (в случае установки Python в C:\Python24). Откройте его в текстовом редакторе и добавьте следующее:
[build]
compiler=mingw32

4. Создание buildout для проекта

Теперь мы готовы создать новую сборку (buildout). "buildout" - это директория, которая содержит все части проекта, включая Zope инстанс, исходники Plone, пользовательские настройки конфигурации и ваш собственный код.

Создайте buildout с помощью:

 

$ paster create -t plone3_buildout myproject

Вам нужно будет ответить на серию вопросов. Если вы хотите использовать существующую установку  Zope вместо того, чтобы загрузить и компилировать новую, укажите абсолютный путь к директории установки. Если вы не хотите, чтобы buildout загрузил Plone продукты ядра, вы можете указать существующую директорию, содержащую все продукты(только для Plone3.0/3.1 - примечание переводчика).  Plone 3 eggs все равно будут загружены, но как вы увидим позже, возможно разделить одну общую директорию eggs между несколькими сборками. Вам нужно будет ввести логин Zope администратора и пароль, и вы можете включить режим отладки (debug mode)  и настройку verbose security (используется для детального вывода ошибок, связанных с настройками безопасности - примечание переводчика) в процессе разработки.

Теперь зайдите в только что созданную директорию myproject и запустите скрипт загрузки buildout (buildout bootstrap script).  Замечание:  Для Plone 3.x необходим Python2.4

$ cd myproject
$ python2.4 bootstrap.py

Будет создано несколько директорий и скриптов и загружены последняя версия пакета zc.buildout. Этот шаг выполняется только один раз.

Чтобы приступить к работе немедленно, выполните:

$ ./bin/buildout

Эта команда читает файл buildout.cfg и выполняет его разнообразные части (parts), устанавливающие Zope, создающие Zope инстанс, загружающие и инсталлирующие Plone. Мы разберем содержание этого файла позже.

Вам нужно запускать ./bin/buildout снова каждый раз при изменении buildout.cfg. Если вы не желаете, чтобы buildout работал online и искала обновления версий для пакетов или загружал другие архивы, вы можете запускать его offline, в режиме не-обновления:

$ ./bin/buildout -No

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

$ ./bin/instance fg

Скрипт instance - аналог zopectl, который можно найти в стандартном Zope инстансе. Вы можете использовать ./bin/instance start для запуска Zope как процесса-демона. Этот скрипт используется также для запуска тестов:

$ ./bin/instance test -s plone.portlets

Команда:

bin/instance console

является эквивалентом bin/instance fg, однако ее запуск не включает явно режим отладки, а полагается на настройку debug-mode в buildout.cfg. Такой способ может быть полезен для запуска Zope в рабочем режиме с помощью команд контроля процессов-демонов  как supervisor.

Как только ваша установка buildout закончена и запущена, вам нужно создать Plone сайт. Зайдите в интерфейс управления Zope (ZMI) и в списке выбора "select type to add.." выберите Plone site (обычно ZMI доступен по адресу http://localhost:8080/manage - примечание переводчика). Заполните необходимые поля и сохраните. Теперь у вас есть  Plone сайт с ID, которое вы указали в форме (созданный Plone сайт доступен по адресу http://localhost:8080/id_сайта - примечание переводчика).

Директории в buildout

Перед тем как мы начнем детально разбирать buildout.cfg, давайте взглянем на директории, которые скрипт buildout создал для нас:
bin/
Содержит разнообразные выполняемые файлы, включая команду buidlout и instance.
develop-eggs/
Содержит егг-пакеты загруженные buildout. 
downloads/
Содержит обычные (не еггофицированные) пакеты такие как архив с исходным кодом Zope 
var/
Содержит log файлы (в var/log)  и файл с данными ZODB (в var/filestorage/Data.fs). Buildout никогда не переписывает эти файлы.
Если вы хотите импортировать файл .zexp, положите его в var/instance/imports.

Раньше нужно было класть этот файл в parts/instance/import,  но это папка пересоздается каждый раз при запуске bin/buildout, поэтому расположение импортных файлов было изменено.

src/
Изначально пустая. Вы можете положить свои собственные егг-пакеты  и сослаться на них в buildout.cfg. Об этом будет рассказано позже.
products/
Аналог директории Products инстанса (пишется с прописной буквы). Если вы разрабатываете Zope 2 продукты старого образца, поместите их сюда.
parts/
Содержит код и данные, которыми управляет buildout. В нашем случае, в директории будет локальная Zope установка, инстанс и исходный код Plone. Обычно вы не должны изменять что-либо в этой директории, так как buildout может уничтожить ваши изменения.

Вы можете зарегистрировать директорию buildout в репозитории исходного кода, чтобы разделить ее среди разработчиков. В этом случае, вам следует игнорировать директории bin/, eggs/, downloads/, var/ и parts/.  Каждый разработчик может запустить bootstrap.py, чтобы получить их заново. Вся конфигурация должна быть в buildout.cfg и весь пользовательский код в src/ или products/. 

 

5. Понимание buildout.cfg

Как управлять главным файлом конфигурации

Важно: Этот документ применим к Plone 3.2 и выше. В версиях 3.2 и ниже buildout.cfg отличается, так как Plone не был полностью еггофицирован.

buildout.cfg - это самый главный файл в окружении buildout. Вот его содержание:

[buildout]
parts =
    zope2
    productdistros
    instance
    zopepy

# Change the number here, and in find-links below, to change the version of
# Plone being used
extends = http://dist.plone.org/release/3.3.5/versions.cfg
versions = versions

# Add additional egg download sources here. dist.plone.org contains archives
# of Plone packages.
find-links =
    http://dist.plone.org/release/3.3.5
    http://dist.plone.org/thirdparty

# Add additional eggs here
eggs =
    
# Reference any eggs you are developing here, one per line
# e.g.: develop = src/my.package
develop =

[zope2]
recipe = plone.recipe.zope2install
url = ${versions:zope2-url}

# Use this section to download additional old-style products.
# List any number of URLs for product tarballs under URLs (separate
# with whitespace, or break over several lines, with subsequent lines
# indented). If any archives contain several products inside a top-level
# directory, list the archive file name (i.e. the last part of the URL, 
# normally with a .tar.gz suffix or similar) under 'nested-packages'.
# If any archives extract to a product directory with a version suffix, list
# the archive name under 'version-suffix-packages'.
[productdistros]
recipe = plone.recipe.distros
urls =
nested-packages =
version-suffix-packages = 

[instance]
recipe = plone.recipe.zope2instance
zope2-location = ${zope2:location}
user = admin:admin
http-address = 8080
# comment the following two options in production sites
debug-mode = on
verbose-security = on

# If you want Zope to know about any additional eggs, list them here.
# This should include any development eggs you listed in develop-eggs above,
# e.g. eggs = Plone my.package
eggs =
    Plone
    ${buildout:eggs}

# If you want to register ZCML slugs for any packages, list them here.
# e.g. zcml = my.package my.other.package
zcml = 

products =
    ${buildout:directory}/products
    ${productdistros:location}

[zopepy]
recipe = zc.recipe.egg
eggs = ${instance:eggs}
interpreter = zopepy
extra-paths = ${zope2:location}/lib/python
scripts = zopepy

Давайте пройдемся по этому файлу:

Главная секция [buildout]

Эта секция - стартовая точка всего файла. Это список частей, которые сконфигурированы в отдельные секции далее в этом файле. Каждая часть имеет соответствующий рецепт - имя егг-пакета, который знает как выполнять конкретную задачу, например, собрать Zope или создать инстанс. Рецепт обычно использует несколько параметров конфигурации.

Наши глобальные настройки следующие:

[buildout]
parts =
    zope2
    productdistros
    instance
    zopepy

find-links =
    http://dist.plone.org/release/3.3.5
    http://dist.plone.org/thirdparty

eggs =
    
develop =

Эта конфигурация определяет, что части zope2, productdistros, instance и zopepy будут выполнены в заданном порядке. Далее мы говорим buildout, что он может искать по нескольким адресам егг-пакеты для загрузки. Также он всегда будет искать в Cheese Shop.

Заметьте, что части конфигурации разбиты в несколько строк. Чтобы это работало, все строки должны начинаться с  4 пробелов.

Дальше мы можем перечислить все егг-пакеты, который buildout должен загрузить и установить. Список можем включать указание версий. Например, если вы хотите sqlalchemy 0.3, а не 0.4, вы можете добавить следующее:

eggs = 
    sqlalchemy>=0.3,<0.4dev

Пожалуйста заметьте, что для работы Plone нужна python библиотека для работы с изображениями (PIL). В это примере допускается, что у вас уже есть эта библиотека установленная и доступная для python-интерпретатора, в противном случае вы можете установить в ваш buildout слегка модифицированную (чтобы обойти несколько общих проблем) версию с "thirdparty" python репозитория, добавив ее имя в список егг-пакетов:

eggs =
    PILwoTk

И полный путь к пакету в секции find-links:

find-links = http://dist.plone.org/thirdparty/PILwoTk-1.1.6.4.tar.gz

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

eggs =
    my.package

develop = 
    src/my.package

Здесь предполагается, что в директории src/ существует егг-пакет с именем my.package. Немного позже мы узнаем как создавать такие пакеты. Заметьте, что мы должны также перечислить my.package как зависимый егг-пакет: егг-пакеты в разработки не добавляются автоматически в "рабочий набор" пакетов для Zope.

Строки extends и versions

Эта часть внедряет Plone 3.2. Она ссылается на удаленный файл, где указаны версии всех необходимых пакетов. Посмотрите этот файл самостоятельно, чтобы увидеть как эти зависимости указаны.

# Change the number here, and in find-links below, to change the version of
# Plone being used
extends = http://dist.plone.org/release/3.3.5/versions.cfg
versions = versions

Если вы хотите использовать локальную копию файла вместо удаленного, чтобы иметь возможность работать оффлайн, загрузите его в директорию buildout и сделайте такую ссылку:

extends = versions.cfg

Секция [zope2]


Это часть собирает Zope 2, используя рецепт  plone.recipe.zope2install.  Если вы указали существующую Zope установку, то вам эта часть не нужна. В противном случае она выглядит так:

[zope2]
recipe = plone.recipe.zope2install
url = ${versions:zope2-url}

Здесь мы используем путь для загрузки Zope, указанный в файлу versions. Это обеспечивает нам получение рекомендованной версии Zope. Вы можете указать адрес для загрузки вручную, если вы хотите использовать другую версию Zope. 

После выполнения рецепта, Zope 2 будет установлен в parts/zope2. Домашняя директория Zope станет parts/zope2/lib/python. 

 

Секция [productdistros]

Эта секция использует рецепт plone.recipe.distros ,  который загружает дистрибуции  (архивы) продуктов в стиле Zope 2 и делает их видимыми для Zope. Она пустая в начале:

[productdistros]
recipe = plone.recipe.distros
urls =
nested-packages =
version-suffix-packages =

Однако, вы можете перечислить любое количество загрузок. Рецепт также может работать с архивами, которые содержат одну директорию верхнего уровня, в которую вложены директории продуктов (вложенные пакеты) или пакеты, название директории которых содержат указание версии и поэтому должно быть переименованы для получения действительной директории продукта (продукты с суффиксом версии).

Предположим у нас есть такие дистрибуции:

# A typical distribution 
ExampleProduct-1.0.tgz
 |
 |- ExampleProduct
     |
     |- __init__.py
     |- (product code)

# A version suffix distribution
AnotherExampleProduct-2.0.tgz
 |
 |- AnotherExampleProduct-2.0
     |
     |- __init__.py
     |- (product code)

# A nested package distribution
ExampleProductBundle-1.0.tgz
 |
 |- ExampleProductBundle
     |
     |- ProductOne
     |   |- __init__.py
     |   |- (product code)
     | 
     |- ProductTwo
         |- __init__.py
         |- (product code)

Вот так может выглядеть эта часть, если мы хотим установить эти три пакета:

[productdistros]
recipe = plone.recipe.distros
urls =
    http://example.com/dist/ExampleProduct-1.0.tgz
    http://example.com/dist/AnotherExampleProduct-2.0.tgz
    http://example.com/dist/ExampleProductBundle-1.0.tgz
nested-packages = ExampleProductBundle-1.0.tgz
version-suffix-packages = AnotherExampleProduct-2.0.tgz

Вы можете указать несколько загрузок на отдельных строчках. После выполнения  рецепта, директории продуктов могут быть найдены в parts/productdistros.

Секция [instance]

Секция instance собирает все вместе: она конфигурирует инстанс, используя скрипт plone.recipe.zope2instance . Так она выглядит:

[instance]
recipe = plone.recipe.zope2instance
zope2-location = ${zope2:location}
user = admin:admin
http-address = 8080
# comment the following two options in production sites
debug-mode = on
verbose-security = on

eggs =
    Plone
    ${buildout:eggs}

zcml = 

products =
    ${buildout:directory}/products
    ${productdistros:location}

Здесь мы определяем zope2-location значением переданным из части [zope2]. Потомы мы определяем логин и пароль администратора, который используется для создания первоначальной базы, и порт, c которым будет связан Zope. Мы также включаем режим отладки и режим verbose security ("многословная безопасность" - в этом режиме выводится полный лог ошибок, связанных безопасностью). Эти режимы полезные в режиме отладки, но не забудьте выключите их на рабочих сайтах, так как они могут нарушить безопасность ваших сайтов. Эти опции используются для генерации соответствующего файла zope.conf для инстанса. Обратитесь к описание рецепта на  Cheese Shop, чтобы узнать подробности о доступных опциях конфигурации.

Далле мы определяем какие егг-пакеты будут доступны в Zope. Мы ссылаемся на глобальную переменную egss из секции [buildout] и также на сам Plone. Вы можете добавить сюда дополнителые егг-пакеты, хотя обычно проще указывать их вверху файла, так, чтобы они включались в набор ${buidout:eggs}.

Файлы configure.zcml егг-пакетрв и продуктов, в которых нет поддержки z3c.autoinclude и ненаходящиеся в пространстве имен Products не загружаются Zope 3 автоматически. Чтобы загрузить ZCML файлы, мы может заствить buildout создать ZCML cлаг, перечислив пакет в опции zcml:

zcml =
    my.package
    my.package-overrides

Мы предполагаем, чтто my.package был определен ранее в buildout. Эта конфигурация обеспечит загрузку двух файлов: configure.zcml и overrides.zcml из этого пакета. Со временем необходимость в этих записях должна уменьшится, так как поддержка z3c.autoinclude становится более распространенной.

Наконец, мы перечисляем различные директории, которые содержат Zope 2 продукты - наподобие директории Products в традиционном инстансе. Заметьте, что директория products/ идет первой, за ней следуют загружаемые продукты из  части  [productdistros].
После выполнения рецепта, домашней директорией Zope станет parts/instance и контролирующий скрипт ./bin/instance будет создан.

Секция [zopepy]

Финальная секция создает python интерпретатор, в котором есть все егг-пакеты (но нет Zope 2 продуктов), которые будут в Zope после старта.  Это может быть полезно для тестирования.

[zopepy]
recipe = zc.recipe.egg
eggs = ${instance:eggs}
interpreter = zopepy
extra-paths = ${zope2:location}/lib/python
scripts = zopepy

Здесь мы копируем егг-продукты из секции [instance] и включаем в pythonpath домашнею директорию Zope.

После выполнения рецепта скрипт ./bin/zopepy будет создан.

6. Cоздание дефолтного файла buildout

Этот файл позволяет разделять конфигурацию для нескольких билдаутов и сохранить немного вашего времени и места на диске.

Чтобы установить глобальные настройки, затрагивающие все билдауты, создайте директорию .buildout (начинается с точки)  в вашей домашней директории и добавьте файл default.cfg. Любая настройка установленная здесь будет применена к соответствующему разделу в любом файле buildout.cfg, который вы выполните, пока не будет переписана более специфичной опцией в самом файле buildout.cfg.

Наиболее распространенные опции:

executable
Определяет python интерпретатор отличный от системного.  Это полезно, если у вас, скажем, установлен Python 2.5, но вы хотите, чтобы билдауты использовали Python 2.4 установленный где-либо.
eggs-directory
Определяет директорию, куда загружаются егг-пакеты. Это позволяет нескольким билдаутом разделять одни и те же пакеты, сохраняя место на диске и сокращая время загрузки. Заметьте, будут активированы только те пакеты, которые явно нужны для конкретного билдаута. Эта директория может содержать намного больше пакетов (или много разных версий одних и тех пакетов), чем те, которые используются в данный момент.
download-cache
Определяет общую директорию для загрузки архивов. Это опять может сохранить дисковое пространство и время загрузки. ЗАМЕЧАНИЯ: до zc.buildout 1.0 она называдась download-directory.
extends-cache
Определяет общую директорию для расширений конфигурация билдаута, которые загружаются по URL.  В Plone 3.2 так определяется версии егг-пакетов . Эта опция была добавлена в zc.buildout 1.4.1, до этого  оффлайн режим в сочетании с extends URL работать не будет.

Пример ~/.buildout/default.cfg:

[buildout]
executable = /opt/python24/bin/python
eggs-directory = /home/username/.buildout/eggs
download-cache = /home/username/.buildout/downloads
extends-cache = /home/username/.buildout/extends

Предполагается, что Python 2.4 установлен в /opt/python2.4. Вы должны создать директории eggs и downloads в ~/.buildout директории, чтобы последние две опции работали.

7. Установка сторонних продуктов

Как устанавливать новые пакеты

Способ установки сторонних продуктов зависит от того, является ли пакет "яйцом" или традиционным Zope 2 продуктом.

Установка яиц

Пока релиз пакета есть на PyPi или еще где-нибудь, buildout может скачать и установить его, включая любые явно указанные зависимости. Просто перечислите егг-пакет и возможно его версию (в противном случае вы получите последнюю доступную версию) в опции eggs: 

[buildout]
...
eggs = 
    elementtree
    borg.project>=1.0b1,<2.0dev

Если вы хотите, чтобы buildout искал в отличном от PyPi месте, вы можете добавить URL по которому можно загрузить пакет в find-links. Фактически, у нас уже есть пример этого: elementree может быть найден на http://effbot.org/downloads, а не в PyPi. Итак, у нас есть:

[buildout]
...

find-links =
    http://dist.plone.org
    http://download.zope.org/ppix/
    http://download.zope.org/distribution/
    http://effbot.org/downloads

eggs =
    elementtree

Мы также перечислили несколько мест загрузки Zope и Plone яиц.

Мы снова перезапускаем buildout для вступления изменений в силу:

$ ./bin/buildout

Егг-пакеты в разработке

Если ваш пакет еще не перешел в стадию релиза, или вы хотите отслеживать его в Subversion, сделайте чекаут в директрию src/. Убедитесь, что вы загрузили полностью пакет, включая файл setup.py в корне.  Например, чтобы получить последнюю версию plone.portlets нужно:

$ cd src
$ svn co https://svn.plone.org/svn/plone/plone.portlets/trunk plone.portlets

Потом добавьте следующее в buildout.cfg:

[buildout]
...
eggs =
    ...
    plone.portlets

develop =
    src/plone.portlets

Заметьте, что:

  • Опция develop содержит относительный путь к месту, где находится исходный код егг-пакета. Buildout ожидает найти подходящий файл setup.py в этой директории.
  • Егг-пакеты в разработке всегда имеют приоритет над обычными егг-пакетами.
  • Чтобы пакет был установлен, вам по-прежнему надо добавить его имя в опцию egg.
  • При переопределении егг-пакета, поставляемого с Plone, вам может понадобиться указать его в секции eggs части [plone]:
[buildout]
...
develop =
    src/plone.portlets

...

[plone]
recipe = plone.recipe.plone
eggs = 
    plone.portlets

Это нужно, так как в plone.recipe.plone явно определены версии используемых пакетов для обеспечения правильной работы Plone.

Рецепты buildout (такие как plone.recipe.plone) распространяются в виде егг-пакетов. Вы можете использовать a development egg of a recipe перечислив его в опции develop. Нет необходимости указывать его явно в опции eggs, так как на него ссылается опция recipe соответствующей части.   

Установка традиционного Zope 2 продукта

Распаковка пакета в папку products внутри buildout - это самый простой способ поставить традиционный Zope 2 продукт. 

Однако, этот подход затрудняет распространение вашего проекта и разделение его с другими разработчиками. Естественно лучше позволить билдауту загружать и устанавливать пакеты самостоятельно. Вы можете это сделать с помощью секции [productdistros] в buildout.cfg. Например, вы можете установить продукт c именем ExampleProduct и набор продуктов с именем ExampleProductBundle:

[productdistros]
recipe = plone.recipe.distros
urls =
    http://example.com/dist/ExampleProduct-1.0.tgz
    http://example.com/dist/ExampleProductBundle-1.0.tgz
nested-packages =
    ExampleProductBundle-1.0.tgz
version-suffix-packages =

Заметьте, что наш вымышленный ExampleProductBundle распространяется в виде единой директории, содержащей несколько продуктов в поддиректориях, поэтому мы перечисляем его в nested-packages.

Как всегда, если вы поменяли buildout.cfg, вы должны перезапустить buildout:

$ ./bin/buildout

Управление ZCML файлами

Важно понимать, что Zope автоматически не загружает файлы configure.zcml пакетов, расположенных не в пространстве имен Products.* и без поддержки z3c.autoinclude(смотри следующую страницу для более детальной информации о z3c.autoinclude). Вместо этого, вы должны явно создать ссылку на пакет. Buildout создаст такую ссылку (известную как ZCML слаг) для имен, перечисленных в опции zcml в часте [instance]. Далее пример конфигурации, обеспечивающей доступность borg.project в Zope:
[buildout]
...
eggs =
    elementtree
    borg.project

...

[instance]
...
zcml = 
    borg.project

Вы можете использовать следующий синтаксис, если надо загрузить overrides.zcml или meta.zcmlес:

zcml =
    some.package
    some.package-overrides
    some.package-meta

Продукты политики

Многие разработчики предпочитают создавать единый продукт политики (известные также как продукт развертывания), которые организуют различные зависимости. Если у вас есть такой продукт, вы можете захотеть включить  зависимости прямо из продукта политики в configure.zcml таким образом:

<configure xmlns="http://namespace.zope.org/zope">

    <include package="borg.project" />

</configure>

В этом случае, вам по-прежнему нужно создать один слаг (используя опцию zcml как показано выше) для продукта политики.

8. Cоздание нового пакета

Создание традиционного Zope 2 продукта

Положите традиционный Zope 2 продукт в директорию products/ и перезапустите Zope. Никаких дополнительных действия больше не нужно. Как было объяснено раньше, размещенные здесь продукты будут автоматически обнаружены при старте и  файлы configure.zcml будут также выполняться автоматически.

Создание егг-пакета

Если вы используете традиционные продукты, вы не получаете дополнительные преимущества егг-пакетов такие, как автоматическое управление зависимостями, распространения через Cheese Shop  и вложенное пространство имен.

Самый простой пусть создания нового егг-пакета - использование команды paster, которую мы уже использовали для создания buildout. Для создания базового пакета с пространством имен верхнего уровня и специфичным именем, зайдите в директорию src и выполните: 
$ cd src

$ paster create -t plone myorg.mypackage

Вам будет задана серия вопросов. Убедитесь, что пространство имен пакета и имя пакета соответствуют имени яйца. В нашем случае, пространство имен - myorg, а имя пакета - mypackage. Ответьте  False на вопрос является ли ваш пакет "zip safe" и введите остальные метаданные.

Теперь у вас есть:

  • Файл setup.py который содержит введенные вами метаданные
  • Пакет в myorg.mypackage/myorg/mypackage.  Ваш исходный код будет здесь.
  • "Cкелет" файлов configure.zcml, tests.py и некоторых других.
  • Немного общей документации в myorg.mypackage/docs.

Конечно, вы должны добавить этот пакет в ваш buildout. В buildout.cfg у вас может быть:

[buildout]

...

eggs =

    ...

    myorg.mypackage



develop =

    src/myorg.mypackage

Пока вы не планируете подключать этот пакет из какого-нибудь другого (или использовать автоматическую ZCML загрузку, которой далее), вы скорее всего должны добавить ZCML слаг:

[instance]

...

zcml =

    myorg.mypackage

Не забудьте перезапустить buildout:

$ ./bin/buildout

Автоматическая загрузка ZCML для вашего пакета

Если вы не планируете подключать ваш пакет из другого пакета, вы все равно можете не использовать ZCMl cлаг в buildout.cfg. Это позволяет избежать повторения имени пакета в файле конфигурации, о котором легко может забыть начинающий интегратор.  Начиная с Plone 3.3, вы можете обеспечить включение ZCMl пакета добавлением следующего кода в setup.py:

setup(...
entry_points="""
...
[z3c.autoinclude.plugin]
target = plone
...)
"""

 Для детальной информации обратитесь к документации setuptools о динамическом обнаружении сервисов и плагинов .

Указание зависимостей

Если ваш пакет имеет явные зависимости, вы можете перечислить их в  setup.py. Таким образом, buidlout автоматически загрузит и установит их. Зависимости перечисляются в аргументе install_requires метода setup(). По умолчанию, здесь есть setuptools, так как нам необходима поддержка пространства имен пакета. Вы можете изменить эту часть следующим образом, если хотите добавить sqlalchemy 0.3 (но не 0.4) и драйвер MySQL-Python:

install_requires=[

          'setuptools',

          'sqlalchemy>=0.3,<0.4dev',

          'MySQL-Python',

      ],

Загрузка яйца в Cheese Shop

Если вы хотите поделиться своим пакетом с Python сообществом и сделать легкой его установку с помощью инструментов подобных buildout и easy_install, вы можете загрузить пакет в Cheese Shop.

Прежде чем сделать это, вы должны:

  • Сделать коммит последних изменений и присвоить тег релизу в системе контроля версий, если необходимо.
  • Удалить(временно) файл setup.cfg: это сделает пакет development release.
  • Убедиться, что номер версии правильный. Используйте общепринятые соглашения для версий, например, "1.0b2" для второй беты версии 1.0, или  "2.1.3rc1" для первого релиз-кандидата версии 2.1.3
  • Если вы используете  Mac OS X, запустите сначала export COPY_EXTENDED_ATTRIBUTES_DISABLE=true в консоле - иначе, яйцо будет содержать вилки ресурсов Mac OS X, которые могут доставить проблемы пользователям Windows.

После того, как все будет готово, выполните следующую команду в директории пакета (например src/myorg.mypackage):

$ python setup.py egg_info -RDb "" sdist register upload

Вам будет предложено создать Chees Shop аккаунт, если у вас еще его нет. Вы можете выполнять загрузка каждый раз, когда вы пожелаете зарелизить новую версию.

9. Конфигурация развертывания

Давайте взглянем на более продвинутую конфигурацию, больше подходящую для развертывания проекта. Сохраните этот файл как deployment.cfg, в корне билдаута рядом с файлом buildout.cfg:   
[buildout]
extends =
    buildout.cfg

parts +=
    debug-instance
    zeoserver
    varnish-build
    varnish-instance

[zeoserver]
recipe = plone.recipe.zope2zeoserver
zope2-location = ${instance:zope2-location}
zeo-address = ${instance:zeo-address}

[instance]
recipe = plone.recipe.zope2instance
zope2-location = ${zope2:location}
zeo-client = true
zeo-address = 8100
zodb-cache-size = 5000
zeo-client-cache-size = 300MB
debug-mode = off
verbose-security = off
eggs += Products.CacheSetup

[debug-instance]
recipe = collective.recipe.zope2cluster
instance-clone = instance
http-address = 8081
debug-mode = on
verbose-security = on

[varnish-build]
recipe = zc.recipe.cmmi
url = http://downloads.sourceforge.net/varnish/varnish-2.0.2.tar.gz

[varnish-instance]
recipe = plone.recipe.varnish
daemon = ${buildout:parts-directory}/varnish-build/sbin/varnishd
bind = 127.0.0.1:8082
backends = 127.0.0.1:8080
cache-size = 1G

Здесь мы видим следующее:

  • Ссылаясь на главный файл buildout.cfg, мы расширяем и переписываем его конфигурации более подходящей для развертывания проекта на сервере.
  • Устанавливаем ZEO сервер с двумя инстансами, instance и debug-instance (см. plone.recipe.zope2zeoserver и plone.recipe.zope2instance)
  • Компилируем  кеш-серевр Varnish (см. plone.recipe.varnish)
Комбинируя файлы конфигурации билдаут, вы можете создать конфигурацию для разных сценариев развертывания. Обратитесь к документации, чтобы узнать больше о продвинутых особенностях buildout.

Для сборки такой среды вы должны явно указать конфигурационный файл:

$ ./bin/buildout -c deployment.cfg

Чтобы запустить Zope и Plone, вам понадобиться запустить ZEO сервер, инстанс и сервер Varnish:

$ ./bin/zeoserver start
$ ./bin/instance start
$ ./bin/varnish-instance

Если нужно поднять инстанс для отладки, вы можете запустить debug-instance в режиме переднего плана:

$ ./bin/debug-instance fg

Также будет созданы скрипты для бекапа ZODB (./bin/repozo) и для паковки базы данных (./bin/zeopack).

Дополнительные опции

zc.builout очень гибкая система. В ней сравнительно просто создавать новые рецепты, можно и комбинировать существующее рецепты более мощным образом. Найти рецепты можно на Cheese Shop или ознакомиться с  исходным кодом собственных рецептов Plone для понимания процесса создания рецептов.

10. Полезные билдаут рецепты

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

  • zc.recipe.egg - устанавливает яйца в директорию eggs билдаут. Также генерирует скрипты в директрии bin билдаут. 
  • infrae.subversion - работа с svn.
  • plone.recipe.zope2install -  устанавливает Zope 2, но не создает инстанс.
  • plone.recipe.zope2instance - создает и настраивает Zope 2 инстанс и управляющие скрипты.
  • plone.recipe.zope2zeoserver - создает и настраивает Zope 2 ZEO сервер и управляющие скрипты.
  • plone.recipe.distros -  устанавливает нееггофицироанные Zope 2 продукты.
  • plone.recipe.apache - устанавливает и настраивает веб сервер Apache.
  • gocept.nginx - конфигурирует nginx
  • plone.recipe.varnish - устанавливает Varnish. Может использоваться не только для Zope сайтов.
  • plone.recipe.squid - устанавливает Squid. Может использоваться не только для Zope сайтов.
  • collective.recipe.omelette - создает унифицированную структуру директорий из пространства имен пакетов, которые являются символическими ссылками на реальное содержимое. Упрощает навигацию.
  • collective.recipe.i18noverrides - создает директорию i18n для одного или нескольких Zope инстансов биладаута. Файлы .po помещенные в это директорию будут переопределять любые другие существующие переводы.
  • zc.recipe.cmmi - автоматизирует установку и конфигурация исходного кода дистрибутива(The Configure-Make-Make-Install).
  • plone.recipe.command - выполнение произвольных команд операционной системы.