zc.buildoutを使ってプロジェクトを管理する
本文書は、Managing projects with zc.buildoutを日本語に翻訳したものです。
日本語版更新履歴:
- 2009年02月09日・日本語対応注意事項、Plone3.2.1導入時の注意事項追加
- 2009年02月08日・英語版の最新に合わせて内容を調整。翻訳文の修正。
はじめに
あるいは、通常の方法でのZopeインスタンスの何が問題なのか?
このチュートリアルはどのようにPlone3を「buildout」を使ってインストールするか、そして、Ploneの機能を拡張するプロダクトを加えるときにbuildoutをどう使用するかを紹介します。buildoutは(ZopeとPloneといくらかのサードパーティプロダクツあるいは必要なライブラリを含む)依存関係とあなたのプロジェクトのための作成したコードの管理ができる環境となります。自分で開発してコードを書く予定がなくても、しっかりとよくテストされた方法であるbuildoutを利用して簡単にPloneをインストールできます。
Plone3.0以前、GUIインストーラーを使わなかった多くの開発者とユーザーは、いくつかのプロダクトをProductsフォルダにドロップすることでZopeインスタンスをセットアップしていました。残念ながらこのアプローチはいくつかの問題を抱えています。
- 従来の方法でインストールされたZopeインスタンスはPython eggとして配布されるかsetuptools名前空間を持つパッケージを使用することができません。Plone3の多くの新しいパッケージはこの方法で作られていて、今後ますます沢山のサードパーティモジュールもそうなるでしょう。
- eggが保有するメタデータにアクセスすることなしに、Zopeの外では再利用できないモノシリックなプロダクトを指向すると、開発者たちは彼らの仕事をより再利用出来る複数のパッケージを考慮に入れることがあまりに時間がかかるか混乱させるとわかるかもしれません。
- いくつかの進んだツールなしに、異なる環境をまたがってセットアップを繰り返すのは面倒です。
今後eggはより重要になってくるので、開発者は自らののコードを管理するのにもっと適切なツールを使うことを検討すべきです。zc.buildoutはこのあと「buildout」としてだけ言及するそういったツールの一つです。このチュートリアルではデプロイメントと同様に日々の開発のためにbuildoutを使う方法を紹介します。
パッケージ、プロダクトとエッグ
さらに詳細な中核のコンセプトを見てみましょう。
専門用語
先に進む前にいくつかの専門用語を正しく理解しましょう。
- ソフトウェアホーム
全てのPythonコードを含む(ファイルシステム上の)Zopeをインストールしたディレクトリの中にZopeアプリケーションサーバーのコアができます。様々な種類のZopeパッケージはここに入ります。また$SOFTWARE_HOME環境変数の値の参照先となります。それはシステムによって異なり、パッケージあるいは自分でどこにZopeをインストールしたかによって変わります。この値は ZMI > Control Panelで見つけることができます。
- Zopeインスタンス
HTTPとZopeのデータベース(ZODB)との通信はOS処理しています。言い換えれば、Zopeのサーバープロセス。Pythonコードであり設定ファイルがこのプロセスを実行するのに必要です。Zopeインストーラーにある「mkzopeinstance.py」スクリプトは、新たにインスタンスを設けるのに使います。ひとつひとつのインスタンスは中にはサーバーを開始、停止するスクリプトがあり、zope.confの設定ファイルがあり、プロダクトを入れるProductフォルダがあり、ZODBを含むData.fsファイルがあります。バックエンドに複数のZEOサーバーを立ててることになります - Python path
Pyhthonインタプリタがモジュールを探すフォルダの順位と場所のことです。sys.pathを記述することで有効にできます。Zopeが稼働しているときは、標準ライブラリとなるインクルードされたグローバルPythonモジュールは、インタプリタのサイトパッケージのディレクトリ、インストールされているサードパーティーの「グローバル」モジュールとegg、Zopeのソフトウェアホーム、インスタンスホームのlib/pythonディレクトリを生成します。ランタイムを実行中、Pythonスクリプトに追加のパスをインクルードすることがでます。 - Pythonパッケージ
一般的には再配布可能なPythonモジュールを指します。最も基本的なパッケージの要素は__init__.pyファイルとPythonで書かれたプログラムコードがあるディレクトリになります。 - Zopeプロダクト
特別な種類のPythonパッケージは以前はZopeを拡張していました。Zopeの古いバージョンでは、すべてのプロダクツはZopeインスタンスのProductsディレクトリの中にディレクトリがあり、そして"Products"という名前で呼ばれ始めたPythonモジュールをもちます。例えば、PloneのコアはProducts.CMFPloneとしてPythonに知られているCMFPloneと呼ばれるプロダクトになります。 - Python egg
Pythonパッケージのパッケージ方法と配布手段です。それぞれのeggは依存関係についての情報同様に、著者名、電子メールアドレス、ライセンス情報などのメタデータとsetup.pyファイルを含んでいます。setuptoolsは、eggの仕組みを実際に動かしているPythonライブラリで、インストールするeggのために依存関係を自動的に見つけてダウンロードを実行します。これは二つの異なるeggに同じ依存関係の異なるバージョンを同時に使用することを可能にします。eggはまた、一般的なプラグイン機能の一つであるエントリーポイントと呼ばれる機能をサポートします。またeggはエントリーポイントと呼ばれる機能をサポートしています。詳細はPEAKウェブサイト(http://peak.telecommunity.com/DevCenter/setuptools)でもっと読む事ができます。 - Pythonパッケージ・インデックス
Pythonコミュニティに存在する何千ものダウンロード可能なパッケージのインデックスです。特定パッケージを検索する機能のあるWEBサイトで提供されています。さらに重要なことは、setuptoolsに基づいたパッケージングツール(特にbuildoutやeasy_install)は、このインデックスを検索してパッケージのダウンロードとeggのインストールを自動で行います。「Cheese Shop」や「PyPI」としても知られます。 - easy_install
Pythonパッケージを見つけ出してPython環境下にインストールするコマンドラインのツールです。easy_installスクリプトはsetuptoolsパッケージの一部で、Pythonパッケージ・インデックスを使用します。 -
Namespace package
同一のトップレベルの名前空間を共有する別々のパッケージを多数配布することを可能するsetuptoolsの機能の一つです。例えば、plone.themaとplone.portletsパッケージはともにトップレベルの「plone」名前空間を共有しますが、それらは別々のeggとして配布されます。インストールした時、それぞれのeggは自分自身のディレクトリ(あるいはそのディレクトリの圧縮されたアーカイブかも知れない)に存在します。名前空間パッケージがなければ、私たちは例えば、plone/themeとplone/portletsのような全ての子パッケージを含んだトップレベルのPloneディレクトリで、1個の巨大なPloneパッケージを配布しなければならなかったでしょう。
魔法のProducts namespace(名前空間)
Zopeがある「プロダクト」を見つけた時、それはZMIのルートにある「Control_Panel/Products」にエントリを作り、「initialize()」メソッドを実行し、Zopeを起動するたびにプロダクツのルートの「__init__.py」ファイルを見つけます。どのパッケージもPloneコンテキストの中で使われるパッケージになる必要はありませんが、プロダクト的な以下のものが求められます。
- GenericSetupプロファイル
- スキンディレクトリは(Zope3スタイルのbrowser viewsでなく)portal_skinsツールにレイヤーとしてインストールされます。
プロダクトを作る最も簡単な方法はProducts以下にegg-readyパッケージを作るのに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」ディレクトリに自分のパッケージを作成して、buildout.cfgの「develop」と「instance/eggs」セクションにその参照の記載を追加します。
develop = src/Products.myproduct ... [instance] ... eggs = ${buildout:eggs} ${plone:eggs} Products.myproduct
「bin/buildout」を実行し、「src」ディレクトリにある自分のegg-readyプロダクトの開発をセットアップをします。完成したら、これを配布用のeggにします。Zope2プロダクトとして「namespace/directory」プロダクツの外でパッケージ(eggで配布されたものを含む)を使用することが可能です。多くの開発者は、フラットな名前空間に全てを保持するのは不自然であると感じて、このアプローチを好みます。
これを行うには追加の作業が必要です。Zope 2.10.4より前では、プロダクト名前空間のプロダクトが必要になります。そのパッケージの「configure.zcml」に以下のように追加しなければなりません。
<configure xmlns="http://namespaces.zope.org/zope" xmlns:five="http://namespaces.zope.org/five"> <five:registerPackage package="." initialize=".initialize" /> </configure>
二番目に重要なことは、プロダクト名前空間の外のパッケージはZope起動時に自動的に検出されないことを理解してください。。もし(大半のパッケージのように)「configure.zcml」ファイルを含んでいるなら、それをどこからか明示的に含まなければいけません。以下のようなものです。
- 他のパッケージのconfigure.zcmlファイル
- Zopeのsite.zcml、全てのZCMLファイルのルート、インスタンスホームの中の「etc」ディレクトリの中で見つかる場所
- ZCMLのスラグは、zopeインスタンスの「etc/package-includes」ディレクトリの中に「my.package-configure.zcml」のような名前で1行で作られます。
全てのケースでシンタックスは同じです。
<include package="my.package" file="configure.zcml" />
もし、「meta.zcml」または「overrides.zcml」ファイルがあるなら、これらのための「<include />」ディレクティブを加えることができます。スラグを使用しているなら、それに従って、例えば「my.package-meta.zcml」または「my.package-overrides.zcml」と命名しなければなりません。スラグは1つ以上の行を含むことができません。
このチュートリアルの後半で、どうやってbuildoutは自動的にslugの管理が可能なのかに触れます。
前提条件
開始する前にあなたに必要ないくつかのこと
ZopeとPloneを管理することができるbuildoutを作る前に、気をつけるべき前提条件があります。
最初に、もし既にインストールされていなければ、適切なPythonインタープリターが必要でしょう。
- 自分のプラットフォームにPython2.4をインストールし、システムのPATHにそれを追加します。コマンドラインで「python -v」とタイプしたときに「Python2.4」と表示されればOKです。
- もしRPMのようなOSのパッケージを使ってPythonをインストールしていたなら、python-develといった開発パッケージを必ず手に入れておいてください。これに含まれるPythonヘッダファイルをももに後でZopeをコンパイルします。もしあなたがソースからコンパイルした、あるいはPython Windowsインストーラーを使ってインストールしていたら、既にヘッダファイルは入っていいます。。
- Pythonインタープリタの中に「Python Imaging Library(PIL)」をインストール。
そして「ez_setup.py」をダウンロードして下記のように実行します。
$ python ez_setup.py
これはsetuptoolsと「easy_install」スクリプトをダウンロードしインストールします。コンソールの出力を見るとeasy_installがどこにインストールされたかがわかります。もし自分のシステム「PATH」に記述がなければ、このディレクトリを追加するべきです。
最後に「easy_install」を使ってZopeとPloneの開発のためのスケルトンのテンプレート集の「ZopeSkel」をインストールします。
$ easy_install -U ZopeSkel
これは「Pasteスクリプト」と様々なその他の依存関係を取得します。もし自分のシステムのパスにPythonコンソールスクリプトディレクトリ(easy_installの場所)を追加したなら、「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環境を使っているなら、いくつか追加の作業が必要になります。
最初に、Python2.4のために「Python Win32 エクステンション」をインストールします。
もしバイナリのインストーラを使うより自分でZopeをコンパイルするつもり、またはCエクステンションでeggをコンパイルする必要があるなら、「mingw32コンパイラ」が必要です。
インストーラが尋ねた時最小限の「base」と「make」モジュールの選択を確実にしてください。デフォルトではこれは「C:\MingW32」にインストールされます。インストールディレクトリの内側に、例えば「C:\MingW32\bin」のようなbinディレクトリがあるでしょう。システムPATHにこれを追加します。
最後に、「mingw32コンパイラ」を使ってPythonのdistutilsパッケージを設定する必要があります。(デフォルトのC:\Python24にpythonがインストールされていると仮定して)「C:\Python24\Lib\distutils」ディレクトリの中に「distutils.cfg」というファイルを作成します。これをノートパッドなどで編集して、以下を追加します。
[build] compiler=mingw32
プロジェクトのためにbuildoutを作成する
依存関係の通りにPloneとその他のサードパーティ・プロダクトを追加して、プロジェクトのために新しいbuildoutを作成する方法
新しいbuildoutを作成する準備をします。「buildout」とはプロジェクトを作る全てのパーツ、Zopeインスタンス、Ploneソース、カスタムコンフィギュレーションオプションとあなたのプロジェクトのソースコードを含むディレクトリです。
以下のようにして作ります
$ paster create -t plone3_buildout myproject
このあといくつかの質問に答えていきます。もし「buildout」をダウンロードしてコンパイルするより既存のインストールされているZopeを使いたいなら「zope2_install」に絶対パスで指定します。
同様に、もし「buildout」にコアのPloneプロダクツのダウンロードしてほしくないなら、全てのプロダクツを含む既存のディレクトリを指定できます(Plone3のeggをダウンロードするでしょうが、後で見るように複数のbuildout間でeggのディレクトリを共有可能です)。Zope管理者権限のユーザー名とパスワードを入力する必要があるかもしれません。また必要があれば開発の間は「verboseセキュリティ」と「デバッグモード」をオンにします。
新しい自分のプロジェクト用ディレクトリを作成し、buildout bootstrapスクリプトを実行します。
$ cd myproject $ python bootstrap.py
これはディレクトリとスクリプトを幾つか作成し、「zc.buildout egg」の最新バージョンをダウンロードします。このステップは最初に一度行います。
開始するには以下のコマンドを実行します。
$ ./bin/buildout
これは生成された「buildout.cfg」ファイルを読み込み、記載されているなパートを実行します。Zopeのセットアップ、Zopeインスタンスの作成、Ploneのダウンロードとインストールを行います。すぐ後でこのファイルについて詳細に説明します。
「buildout.cfg」を変更する度に「./bin/buildout」コマンドを実行する必要があります。もし自分のbuildoutにオンラインでeggのアップデートバージョンを探したりその他のアーカイブをダウンロードしたりしたくないならbuildoutをオフラインモードとしてアップデートせずに実行することができます。
$ ./bin/buildout -No
Zopeを起動します。
$ ./bin/instance fg
「instance」スクリプトは標準のZopeインスタンスにある「zopectl」と類似のものです。「./bin/instance」を使ってZopeをデーモンモードで起動することができます。またテストを実行するのに下記を使えます。
$ ./bin/instance test -s plone.portlets
buildoutのディレクトリ
「buildout.cfg」の中に入る前に、「buildout」で生成されるディレクトリを少し見てみましょう。
bin/
各種の実行可能な「buildout」コマンドとZopeコントロールスクリプトの「instance」を含んでいます。
eggs/
buildoutによってダウンロードされたeggが入ります。これらは「bin」ディレクトリのコントロールスクリプトによって明示的に起動されます。
downloads/
Zopeのソースコードアーカイブのようなeggでないダウンロードを含みます。
var/
ログファイル(var/logの中)とファイルストレージのZODBデータ(var/filestorage/Data.fsの中)を含んでいます。Buildoutはこれらを決して上書きしません、
src/
最初は空です。自分で開発したeggと「buildout.cfg」の中で参照する場所として記載できます。詳細は後ほど。
products/
これはZopeインスタンスのProductsディレクトリ(大文字で始まっている違いに注意)に似ています。もしいくつかの古いZope2形式のプロダクトを開発するなら、この場所で行います。ここにbuildoutは自動的にダウンロードしプロダクツのアーカイブを管理します。しかし、自分でプロダクトの依存関係を手動で行いたい、あるいはSubversionからチェックするときもこの場所で行います。
parts/
buildoutによって管理されるデータとコードを含みます。ここでは、ローカルにインストールされたZope、buildoutで管理されるZopeインスタンスとPloneのソースコードを含みます。通常は、buiodoutがあなたの変更を上書きしてしまうかもしれないので、このディレクトリは何も修正しないほうがよいでしょう。
開発者間で共有しているソースコードリポジトリをbuildoutディレクトリの中でチェックできます。この場合、「bin/」,「eggs/」,「downloads/」,「var/」と「parts/」ディレクトリを無視した方がいいでしょう。各開発者はこれを戻すのに「bootstrap.py」を実行でき、また通常はローカルへのコピーが必要となるでしょう。全てのコンフィグレーションは「buildout.cfg」ファイルの中にあり、そして全てのカスタムコードは「src」あるいは「products」ディレクトリに配置します。
buildout.cfgを理解する
メインの buildout コンフィグレーションファイルの管理方法
「buildout.cfg」は新しいbuildout環境のなかのもっとも重要なファイルです。以下のようになります。
[buildout] parts = plone zope2 productdistros instance zopepy # Add additional egg download sources here. dist.plone.org contains archives # of Plone packages. # ここで追加のeggのダウンロードソースを加えます。dist.plone.orgは # Ploneパッケージのアーカイブを含みます find-links = http://dist.plone.org http://download.zope.org/ppix/ http://download.zope.org/distribution/ http://effbot.org/downloads # Add additional eggs here # elementtree is required by Plone # ここで追加のeggを加えます。elementtreeはPloneに必要とされています。 eggs = elementtree # Reference any eggs you are developing here, one per line # e.g.: develop = src/my.package # あなたがここで開発するあらゆるeggの参照で、1行に一つです。 # 例えば:develop = src/my.package develop = [plone] recipe = plone.recipe.plone [zope2] recipe = plone.recipe.zope2install url = ${plone: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'. # このセクションを使って追加となる古いスタイルのプロダクトをダウンロードします。 # urlsの下にプロダクトtarballの全てのURLを記載してください(空白で分離するか、 # 字下げされた次の行とでいくつかの行に改行)。 # アーカイブがトップレベルディレクトリの中にいくつかのプロダクトを含むなら、 # nested-packagesの下にアーカイブファイル名(すなわち、URLの最後の部分、 # 通常、tar.gz接尾語あるいは類似のもの)を記載します。 # バージョン情報からプロダクトディレクトリにどれかのアーカイブを抽出するなら、 # '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 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 = ${buildout:eggs} ${plone:eggs} my.package # 追加のあらゆるeggについてZopeに知らせたい時、ここに記載します。 # これは上のdevelop-eggsに記載した開発中のeggを含んだ方がいいでしょう。 # 例: eggs = ${buildout:eggs} ${plone:eggs} my.package eggs = ${buildout:eggs} ${plone:eggs} # If you want to register ZCML slugs for any packages, list them here. # e.g. zcml = my.package my.other.package # もしいくつかのパッケージの為にZCMLスラグを登録したいなら、ここに記載します。 # 例: zcml = my.package my.other.package zcml = products = ${buildout:directory}/products ${productdistros:location} ${plone:products} [zopepy] recipe = zc.recipe.egg eggs = ${instance:eggs} interpreter = zopepy extra-paths = ${zope2:location}/lib/python scripts = zopepy
ブロック単位でこのファイルを通しで見てみましょう。
メインのbuildoutセクション
[buildout]セクションはファイルの出発点です。
このファイルの後半で別々のセクションに設定されるパートの名称を記載します。各パートには、例えば、Zopeをビルドする、あるいはZopeインスタンスを作成するなどの特定のタスクを実行する方法を知っているeggの名前の「recipe」と関連づけられます。通常「recipe」にはいくつかの設定オプションがあります。
グローバルセッティングは次のようになっています。
[buildout] parts = plone zope2 productdistros instance zopepy find-links = http://dist.plone.org http://download.zope.org/ppix/ http://download.zope.org/distribution/ http://effbot.org/downloads eggs = elementtree develop =
これは、「parts」の「plone」、「zope2」、「productdistros」、「instance」、および「zopepy」が順番で実行されるよう指定しています。そして、ダウンロードのためにeggを探すとき、buildoutいくつかのURLの1つが検索可能なことを伝えます。それは常にCheese Shopを探すことになります。
次に、buildoutでダウンロードしてインストールしたい、あらゆるeggを記載できます。バージョンの指定が必要かもしれません。例えば、SQLAlchemy0.3が欲しくて0.4ではない場合、次のように記載できます。
eggs = elementtree sqlalchemy>=0.3,<0.4dev
最後に、eggがソース形式で抽出されるディレクトリを指定する事によって開発用eggを記載できます。
例えば::
eggs = elementtree my.package develop = src/my.package
これは「my.package」と呼ばれるeggが「src」ディレクトリ以下にあることを前提とします。このチュートリアルの少し後で、このようなeggを作る方法を学びます。開発用eggはZopeのためにインストールされたeggの「動作セット」に自動的に追加されないため、実際のeggの依存関係について「my.package」を記載しなければならない点に注意して下さい。
[plone]セクション
これはとてもシンプルです。Ploneのプロダクツとeggをダウンロードするのにplone.recipe.ploneを使うだけです。
[plone] recipe = plone.recipe.plone
これは有効な最新リリースを対象にします。plone.recipe.ploneのためのバージョン番号はPlone自身のためのバージョン番号に一致します。従って、3.1でなく確実3.0.xリリースを得るにはこうします。
[plone] recipe = plone.recipe.plone>=3.0,<3.1dev
recipeが実行される時、Ploneのプロダクトは「parts/plone」にインストールされます。eggは後の[instance]セクションで参照されるbuildoutの変数 ${plone:eggs} を通して有効にされ、そしてZope推奨バージョンのURLは変数 ${plone:zope2-url} で有効です。
[zope2]セクション
このパートではplone.recipe.zope2installを使ってZope2をビルドします。もし、既にインストールされているZopeを指定するなら、この部分は必要ありません。そうでなければ、このようになります。
[zope2] recipe = plone.recipe.zope2install url = ${plone:zope2-url}
ここで、[plone]部分によって外に送られているようにZopeのためのダウンロード位置を参照します。これいつもZopeの推奨バージョンを得る事を確実にします。Zopeの異なるバージョンを使用したいなら、代わりに手動でダウンロードURLを指定できます。
recipeが実行されると、Zope2は「parts/zope2」にインストールされます。Zopeソフトウェアホームは「parts/zope2/lib/python」になります。
[productdistros]セクション
これはZope2スタイルの配布(アーカイブ)のダウンロードを可能にし、Zopeで利用可能にするrecipe、plone.recipe.distros を使います。
これは最初は空です。
[productdistros] recipe = plone.recipe.distros urls = nested-packages = version-suffix-packages =
しかし、いろいろなダウンロードを記載できます。recipeは実際のプロダクトディレクトリ(入れ子にされたペッケージ)のバンドルを含む一つのトップレベルディレクトリを含むアーカイブ、あるいはディレクトリ名のバージョン番号を持ち、実際のプロダクトディレクト(バージョン記載のパッケージ)を手に入れるためにリネームされる必要があるパッケージに対処できます。
以下の配布ケースを例にすると:
# 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)
上記の3つのディトリビューションをインストールするとき、パーツへの記載は以下のようになります。
[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
行を分ける事で多数のダウンロードを指定できます。recipeが実行される時、ダウンロードしたプロダクトのためのプロダクトディレクトリは「parts/productdistros」にあります。
[instance]セクション
インスタンスセクションは全部まとめて引きだします。plone.recipe.zope2instanceのスクリプトを使ってZopeインスタンスを設定します。以下のようになります。
[instance] recipe = plone.recipe.zope2instance zope2-location = ${zope2:location} user = admin:admin http-address = 8080 debug-mode = on verbose-security = on eggs = ${buildout:eggs} ${plone:eggs} zcml = products = ${buildout:directory}/products ${productdistros:location} ${plone:products}
ここで[zope2]部分からZope2インストールを参照します。もしbuildoutを作成した時に自分で場所を指定したなら、ここに記載されます。そして、初期の管理者ユーザーとパスワード、そしてZope使用するポートを特定します。「debug-mode」と「verbose security」も「on」にします。これらのオプションはこのインスタンスに適した「zope.conf」ファイルを生成するのに使われます。使用できるオプションの詳細は「Cheese Shop」のrecipeページを参照ください。
次に、どのeggがZopeに利用できるようにするかを指定します。これはPloneによって明示されたeggだけでなく[buildout]セクションからのグローバルeggを参照します。ファイルの先頭でこれらを指定するのが一般的に簡単ですが、${buildout:eggs}ワーキングセットのなかに含まれているように、ここに追加のeggを加えることができます。
前に説明したように、Zope3の「configure.zcml」ファイルはeggやプロダクトの名前空間でないパッケージでは自動ではロードされません。通常のパッケージのためにZCMLファイルをロードするには、「zcml」オプションの下にパッケージを記載することでZCMLスラッグを生成するbuildoutを作ることができます。
zcml = my.package my.package-overrides
これはmy.packageがbuildoutの中で以前参照されたと仮定します。このパッケージからメインの「configure.zcml」と「overrides.zcml」の二つを読み込みます。
最後に、私たちは伝統的なインスタンスの中の「Products」ディレクトリと同種のZope2スタイルのプロダクトを含むあらゆるディレクトリを表示します。メインのbuildoutディレクトリの「products/」ディレクトリがどのように最初に来て、[productdistros]部分でダウンロードされるプロダクトが次に、これに[plone]部分によってダウンロードされたプロダクトが続くようになるかについて注意してください。これはPloneがプロダクトとして出荷しても、トップレベルのproductsディレクトリに同じ名前でプロダクツを置く事によって、(例えばより新しいプロダクトで)それを上書きすることができることを意味します。
recipeが実行される時、Zopeインスタンスホームは「parts/instance」にあり、そしてコントロールスクリプトは「./bin/instance」に作成されています。
[zopepy]セクション
この最後のセクションは全てのeggとZopeが起動中に持つパッケージのPythonインタープリタを作成します。これはテスト用途にとても有効です。
[zopepy] recipe = zc.recipe.egg eggs = ${instance:eggs} interpreter = zopepy extra-paths = ${zope2:location}/lib/python scripts = zopepy
ここでeggを[instance]セクションからコピーし、そしてZopeインスタンスホームのpythonパスにインクルードします。recipeが実行される時、スクリプトは「./bin/zopepy」に作られます。
buildoutデフォルトファイルの作成
複数のbuildoutをまたがって設定を共有することを可能にし、時間とディスクスペースを節約するができます。
すべてのbuildoutに影響を与える「グローバル」オプションをセットするには「.buildout」ディレクトリ(先頭のドットに注意)をあなたのホームディレクトリに作成し、「default.cfg」というファイルを追加します。ここでセットしたいくつかのオプションは「buildout.cfg」ファイル自体に特別に記載したいくつかのオプションによって上書きされない限り、あなたが実行する他のいくつかの「buildout.cfg」の同一のセクションに反映されます。
一般的なオプションは
executable
システムのデフォルトより他のpythonインタープリタを指定する。これは、もしPython2.5をインストールしているが、Python2.4の他のインストールを使うのにあなたのbuildoutを使いたいなら有効です。
eggs-directory
eggがダウンロードされるディレクトリを指定します。これは複数のbuildoutで同じeggを共有することを許可し、ディスクスペースとダウンロード時間を節約します。特定のbuildoutによって明示的に要求されるそれらのeggだけが起動することに注意します。eggディレクトリはいつも使用されるよりもっと沢山のegg(あるいは同パッケージの沢山の異なったバージョン)を含んでいるかもしれません。
download-directory
ダウンロードアーカイブのための共有ディレクトリを指定します。これもまたディスクスペースとダウンロード時間を節約できます。
これは3つ全てを設定した「~/.buildout/default.cfg」の例です。
[buildout] executable = /opt/python24/bin/python eggs-directory = /home/username/.buildout/eggs download-cache = /home/username/.buildout/downloads
これはPthon2.4が「/opt/python2.4に」インストールされていると仮定しています。最後の2つのオプションが動作するには、「~/.buildout」ディレクトリの中にeggsディレクトリとダウンロードディレクトリを作る必要があります。
サードパーティプロダクトのインストール
これらのツールを使って新しいパッケージをインストールする方法
新しいサードパーティプロダクツのインストール方法はそれがeggのパッケージなのか伝統的なZope2プロダクトなのかどうかに依存します。
伝統的なZope2プロダクトのインストール
伝統的なZope2プロダクトを試す最も簡単な方法はbuildoutの内側で「products」フォルダの中にそれを配置することです。もしZopeインスタンスの中の「Products」フォルダにドキュメント参照があれば、これは同じことです。
しかし、このアプローチでは自分のプロジェクトを再配布し、他の開発者と共有することを難しくします。buildoutをダウンロードし、あなたのためにパッケージをインストールさせることがしばしば予測されます。「buildout.cfg」の[productdistros]セクションでこうできます。例えば、プロダクト名「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
eggのインストール
eggがCheese Shopあるいはどこか他でリリースされる限り、buildoutは明示的に指定された依存関係を含んでダウンロードしてインストールできます。単にeggのオプションでは、eggと任意のバージョン(そうでなければ利用可能な最新のもの)を記載します。
[buildout] ... eggs = elementtree borg.project>=1.0b1,<2.0dev
もしbuildoutにCheese Shop以外のインデックスを検索して欲しいなら、eggのためにダウンロード先を含むリンクのURLを追加することができます。実際、この例のように「elementtree」はCheese Shopディレクトリでなく、「http://effbot.org/downloads」に含まれます。要するに以下のようになります。
[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 eggのためのダウンロード先を幾つか記載しています。
変更の効果が現れるようもう一度、buildoutを再実行します。
$ ./bin/buildout
開発用egg
もし、自分のegg用のリリースでない、あるいはSubversionの中でeggをトラッキングをしたいなら「src」ディレクトリ以下をチェックしてください。トップレベルの「setup.py」ファイルを含む全てのeggを得ることを確実にします。例えば、plone.portletsの開発trunkを得るために、eggが実行します。
$ 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
【注意】
- 開発オプションはインストールされたeggソースの相対パスを含みます。buildoutは適した「setup.py」をこのディレクトリの中に見つけることを期待しています。
- 開発用eggはいつも通常のeggより優先されます。
- インストールされるためにeggの名前をeggオプションに記載する必要があります。
- もし自分でPloneに含まれるeggを上書きしているなら、代わりにそれを[Plone]部分のeggセクションに記載する必要があるかもしれません。
[buildout] ... develop = src/plone.portlets ... [plone] recipe = plone.recipe.plone eggs = plone.portlets
これはなぜなら「plone.recipe.plone」は様々なeggのどのバージョンを使用したらよいかに関して非常に明白で、リリースされたPloneと同様に稼働し続けるのを確実にします。
(plone.recipe.ploneのような)buildout recipeはeggとして配布されてます。あなたは開発オプションの下にあるその記載によってrecipeの開発用eggを使用できます。関係のある部分のrecipeオプションによって参照されて以後、eggオプションの下に明示的に記載される必要がありません。
ZCMLファイル管理
ZopeはProducts.* 名前空間の中でないパッケージのために自動的に「configure.zcml」ファイルをロードしないことを認識してください。代わりに、明示的にパッケージに参照をつけなければなりません。buildoutは[instance]パートの箇所でzcmlオプション(ZCMLスラグとして知られる)を作ることができます。以下は「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オプションを使用する)一つのスラグを必要とするかもしれません。
新しいパッケージを作る
あなたのbuildoutに新しいeggベースパッケージを加える方法
新しいカスタムパッケージを追加することはサードパーティのものをインストールするのと大きな違いはありません。
伝統的なZope2プロダクトを作る
伝統的なZope2プロダクトの作成はトップレベルの「products」ディレクトリにそれを置きZopeを再起動します。他に必要なことはありません。前に説明したように、この場所のプロダクトは起動時に自動的に見つけられ、そして「configure.zcml」ファイルは自動的に実行されます。
eggを作る
もちろん、プロダクトを使用しているならば、Cheese Shopの名前空間により配布される自動依存管理を含むeggの付加的な特徴から恩恵を受けることはできません。
新しいeggを作るもっとも簡単な方法は既にbuildoutを作るのに使った「paster」コマンドを使用することです。トップレベルの名前空間(例:あなたの会社)と固有の名前で新しい基本パッケージを作成しに「src」ディレクトリに行き実行します。
$ cd src $ paster create -t plone myorg.mypackage
一連の質問に応える必要があります。名前空間パッケージとパッケージ名がeggの名前に一致することを確認してください。この場合、名前空間パッケージは「myorg」でパッケージ名は「mypackage」です。通常自分のパッケージが「zip safe」かどうかという問いに「False」と答えます。要求された通り、他のメタデータを入力して下さい。
すると以下のものが用意されます。
あなたが入力したメタデータを含んだsetup.py
- 「myorg.mypackage/myorg/mypackage」の中のパッケージ。あなたのソースコードはここにあります。
- 「configure.zcml」のスケルトン、「tests.py」及びいくつかの役に立つ出発点
- 「myorg.mypackage/docs」の中の一般的な文書
もちろんあなたはbuildoutにこのパッケージも追加する必要があります。「buildout.cfg」に以下を含みます。
[buildout] ... eggs = ... myorg.mypackage develop = src/myorg.mypackage
他のパッケージからこのパッケージを含む予定でない限り、多分ZCMLスラグが必要です。
[instance] ... zcml = myorg.mypackage
変更した後にbuildoutを再度実行するのを忘れないように。
$ ./bin/buildout
依存関係の指定
もし自分の新しいパッケージが明快な依存関係を持つなら、setup.pyにそれを記載できます。同様にbuildoutはそれらをダウンロードしてインストールできるようになります。依存関係は「setup()」メソッドの「install_requires 」の中に記載されていて、デフォルトで「setuptools」は名前空間パッケージをサポートするのに必要なのでここに記載されています。「sqlalchemy0.3(しかし、0.4でなく)」と「MySQL-Python」ドライバーを追加するには以下のように修正できます。
install_requires=[ 'setuptools', 'sqlalchemy>=0.3,<0.4dev', 'MySQL-Python', ],
自分のeggをCheese Shopにアップロードする
もし自分のパッケージをその他のPythonコミュニティと共有して、buildoutと「easy_install」のようなツールを使って簡単にインストールしたいなら自分のパッケージをCheese Shopにアップロードできます。
そうする前にやるべきこと
- できるならば、あなたの最新の変更をコミットして、Subversionでリリースにタグを付けてください。
- 「setup.cfg」ファイルを(一時的に)取り外してください: これはパッケージを開発リリースにします。
- 「setup.py」の中のバージョン番号を確実に正しくなるようにします。バージョン1.0の第2ベータのための"1.0b2"あるいはバージョン2.1.3の最初のリリースキャンディデートのための"2.1.3rc1"のような一般的な慣習を使います。
- もしあなたがMac OS X を使っているなら最初にシェル上で「export COPY_EXTENDED_ATTRIBUTES_DISABLE=true」を実行します。さもなければeggはMac OS Xのリソースフォークを含んでしまい、あなたのeggをWindows上で使う時に問題の原因となるでしょう。
準備ができたら、あなたのパッケージのディレクトリ(例えばsrc/myorg.mypackage)から次のコマンドを実行します。
$ python setup.py egg_info -RDb "" sdist bdist_egg register upload
もしまだCheese Shopアカウントを持っていなければ、作成するか尋ねられます。新しいバージョン(おそらく新しいバージョン番号で)をリリースしたい度にこのコマンドを実行します。
デプロイメントコンフィグレーション
デプロイメント・コンフィグレーションのためにbuildoutを使う方法
最後によりデプロイメントに適している、もっと高度な設定を見てみましょう。メインの「buildout.cfg」ファイルに次いで、buildoutのルートにこのファイルを「deployment.cfg」として保存して下さい。
[buildout] extends = buildout.cfg parts = plone zope2 productdistros deploymentproducts zeoserver primary secondary varnish-build varnish-instance [deploymentproducts] recipe = plone.recipe.distros urls = http://plone.org/products/cachefu/releases/1.1/CacheFu-1.1.tgz nested-packages = CacheFu-1.1.tgz version-suffix-packages = [zeoserver] recipe = plone.recipe.zope2zeoserver zope2-location = ${zope2:location} zeo-address = 8100 [primary] recipe = plone.recipe.zope2instance zope2-location = ${zope2:location} zeo-client = true zeo-address = 8100 zodb-cache-size = 5000 zeo-client-cache-size = 300MB user = admin:admin http-address = 8080 debug-mode = off verbose-security = off eggs = ${plone:eggs} ${buildout:eggs} zcml = products = ${buildout:directory}/products ${productdistros:location} ${deploymentproducts:location} ${plone:products} [secondary] recipe = plone.recipe.zope2instance zope2-location = ${zope2:location} zeo-client = true zeo-address = 8100 zodb-cache-size = 5000 zeo-client-cache-size = 300MB user = ${primary:user} http-address = 8081 debug-mode = on verbose-security = on eggs = ${primary:eggs} zcml = ${primary:zcml} products = ${primary:products} zope-conf-additional = zserver-threads 1 [varnish-build] recipe = plone.recipe.varnish:build url = http://puzzle.dl.sourceforge.net/sourceforge/varnish/varnish-1.0.4.tar.gz [varnish-instance] recipe = plone.recipe.varnish:instance bind = 127.0.0.1:8082 backends = 127.0.0.1:8080 cache-size = 1G
これは以下の通りです。
メインの「buildout.cfg」ファイルを参照、拡張し、そしてデプロイメントにもっと適した設定を優先させます。
- ZEOサーバーと2つのクライアントインスタンスとセットアップする(詳細はplone.recipe.zope2zeoserverとplone.recipe.zope2instanceを参照)。
- Varnish cache server(詳細はplone.recipe.varnishを参照)をコンパイルする
- このようにbuildoutの構成ファイルを結合することによって、異なるデプロイメントシナリオに合わせたコンフィグレーションを独自に作成できます。buildoutの高度な特徴についてもっと学ぶにはドキュメントを参照して下さい。
この環境を作るには、あなたは設定ファイルを明示的に指定しなければなりません。
$ ./bin/buildout -c deployment.cfg
ZopeとPloneを起動するには、、ZEOサーバーとVarnishサーバーをスタートする必要があるでしょう。
$ ./bin/zeoserver start $ ./bin/primary start $ ./bin/secondary start $ ./bin/varnish-instance
インスタンスをデバッグモードとする必要があるときは、デバックするインスタンスをフォアグラウンドで起動します。
$ ./bin/debug-instance fg
recipeは(./bin/repozoの中の)ZODBバックアップと(./bin/zeopackの中の)データベースのパックのスクリプトも作成します。
さらなるオプション
zc.buildoutはとても柔軟性のあるシステムです。新しいrecipeを作るのが比較的簡単で、既存のrecipeを強力な方法で結合できます。Cheese Shopの"buildout"でより多くのrecipeを見つける、あるいはrecipeがどのように作成されたかを理解するにはPlone自身のrecipeのいくつかのソースコードを見てください。
日本語環境での注意事項
Python2.4.xの環境化で日本語を適切に扱うことができるように、 「sitecustomize.py」 ファイルを 「 usr/local/lib/python2.4/ 」以下に置きます。内容は次のようになります。
import sys sys.setdefaultencoding("utf-8")
Plone 3.2.1 インストール時の注意事項
ここに記載されている手順でPlone 3.2.1をインストールすると、
/bin/buildout
を実行後にPloneのインストール部分で以下のようなエラーメッセージが大量に表示されます。
Compiling python modules Creating fake eggs Installing productdistros. Installing instance. Getting distribution for 'Plone==3.2.1'. File "build/bdist.linux-x86_64/egg/Products/ CMFPlone/skins/cmf_legacy/TitleOrId.py", line 11 return title SyntaxError: 'return' outside function File "build/bdist.linux-x86_64/egg/Products/ CMFPlone/skins/plone_scripts/getPopupScript.py", line 3 return r""" SyntaxError: 'return' outside function File "build/bdist.linux-x86_64/egg/Products/ CMFPlone/skins/plone_scripts/canSelectDefaultPage.py", line 15 return False SyntaxError: 'return' outside function File "build/bdist.linux-x86_64/egg/Products/ CMFPlone/skins/plone_scripts/my_worklist.py", line 4 return [] SyntaxError: 'return' outside function File "build/bdist.linux-x86_64/egg/Products/ CMFPlone/skins/plone_scripts/selectedTabs.py", line 39 return {'portal':valid_actions[-1][1]} SyntaxError: 'return' outside function File "build/bdist.linux-x86_64/egg/Products/ CMFPlone/skins/plone_scripts/getGlobalPortalRoles.py", line 11 return [r for r in context.portal_membership .getPortalRoles() if r != 'Owner']
このエラーは、PythonがZopeのPython Scriptをコンパイルしようとして発生しているものです。わずらわしい感じがしますが、インストールへの影響はありませんし、インストールされたPloneの信頼性に問題はありません。
以上