=========================
plone.recipe.zope2instance
==========================


This is the doctest for plone.recipe.zope2instance. It ensures the template
works fine. It is based on zc.buildout testing module::

    >>> from zc.buildout.testing import *
    >>> from os.path import join
    >>> import sys, os
    >>> options = globals()

    >>> WINDOWS = sys.platform == 'win32'

Let's create a minimum buildout that uses the current
plone.recipe.zope2instance::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Installing instance...
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    instancehome $INSTANCEHOME
    %define CLIENTHOME .../sample-buildout/var/instance
    clienthome $CLIENTHOME
    <BLANKLINE>
    <BLANKLINE>
    debug-mode off
    security-policy-implementation C
    verbose-security off
    default-zpublisher-encoding utf-8
    http-header-max-length 8192
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    zserver-threads 2
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <eventlog>
    <BLANKLINE>
      level INFO
      <logfile>
        path .../sample-buildout/var/log/instance.log
        level INFO
      </logfile>
    </eventlog>
    <BLANKLINE>
    <logger access>
      level WARN
      <logfile>
        path .../sample-buildout/var/log/instance-Z2.log
        format %(message)s
      </logfile>
    </logger>
    <BLANKLINE>
    <http-server>
      address 8080
    <BLANKLINE>
    </http-server>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <zodb_db main>
        # Main database
        cache-size 30000
    <BLANKLINE>
    # Blob-enabled FileStorage database
        <blobstorage>
          blob-dir .../sample-buildout/var/blobstorage
          # FileStorage database
          <filestorage>
            path .../sample-buildout/var/filestorage/Data.fs
          </filestorage>
        </blobstorage>
        mount-point /
    </zodb_db>
    <BLANKLINE>
    <zodb_db temporary>
        # Temporary storage database (for sessions)
        <temporarystorage>
          name temporary storage for sessioning
        </temporarystorage>
        mount-point /temp_folder
        container-class Products.TemporaryFolder.TemporaryContainer
    </zodb_db>
    <BLANKLINE>
    pid-filename .../sample-buildout/var/instance.pid
    lock-filename .../sample-buildout/var/instance.lock
    python-check-interval 1000
    enable-product-installation off
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>

We should have a blobstorage directory.

    >>> ls('var')
    d  blobstorage
    d  filestorage
    d  instance
    d  log

The blobstorage directory should only be readable by the current user,
otherwise you get a warning when the zope instance starts up.  The
(POSIX) path mode bits should be 0700.

    >>> (os.stat(os.path.join('var', 'blobstorage')).st_mode & 077) == 0
    True


FTP and WebDAV
==============

Let's start off by adding an FTP address::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... ftp-address = 8021
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

Our FTP server should be set up now::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <ftp-server>
      # valid key is "address"
      address 8021
    </ftp-server>
    ...

Next we will add a WebDAV server::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... webdav-address = 1980
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

Our WebDAV server should be set up now::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <webdav-source-server>
      address 1980
      force-connection-close off
    </webdav-source-server>
    ...

Next we will add a WebDAV server with force-connection-close on::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... webdav-address = 1980
    ... webdav-force-connection-close = on
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

Our WebDAV server should be set up now::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <webdav-source-server>
      address 1980
      force-connection-close on
    </webdav-source-server>
    ...

DemoStorage
===========

To have a DemoStorage configuration, you can use demo-storage::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... file-storage = newfs/Data.fs
    ... demo-storage = on
    ...
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        # Main database
        cache-size 30000
    <BLANKLINE>
    # DemoStorage
        <demostorage>
    <BLANKLINE>
        # FileStorage database
        <filestorage>
          path .../sample-buildout/var/newfs/Data.fs
        </filestorage>
    <BLANKLINE>
        </demostorage>
        mount-point /
    </zodb_db>
    ...
    <BLANKLINE>

Verify that demostorage can be disable::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... file-storage = newfs/Data.fs
    ... demo-storage = off
    ...
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.




We should have a zope instance, with a basic zope.conf without demostorage::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        # Main database
        cache-size 30000
    <BLANKLINE>
    # Blob-enabled FileStorage database
        <blobstorage>
          blob-dir .../sample-buildout/var/blobstorage
          # FileStorage database
          <filestorage>
            path .../sample-buildout/var/newfs/Data.fs
          </filestorage>
        </blobstorage>
        mount-point /
    </zodb_db>
    ...
    <BLANKLINE>

You can add file storage to the demo-storage to be able to keep
changes::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... file-storage = newfs/Data.fs
    ... demo-storage = on
    ... demo-file-storage = demofs/Data.fs
    ...
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        # Main database
        cache-size 30000
    <BLANKLINE>
    # DemoStorage
        <demostorage>
    <BLANKLINE>
        # FileStorage database
        <filestorage base>
          path .../sample-buildout/var/newfs/Data.fs
        </filestorage>
    <BLANKLINE>
    <BLANKLINE>
        # FileStorage database
        <filestorage changes>
          path .../sample-buildout/var/demofs/Data.fs
        </filestorage>
    <BLANKLINE>
        </demostorage>
        mount-point /
    </zodb_db>
    ...
    <BLANKLINE>

You can add a blob storage to the demo-storage as well::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... file-storage = newfs/Data.fs
    ... blob-storage = ${buildout:directory}/var/blob
    ... demo-storage = on
    ... demo-file-storage = demofs/Data.fs
    ... demo-blob-storage = ${buildout:directory}/var/demoblob
    ...
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
        <blobstorage base>
          blob-dir .../sample-buildout/var/blob
          # FileStorage database
          <filestorage>
            path .../sample-buildout/var/newfs/Data.fs
          </filestorage>
        </blobstorage>
    ...
        <blobstorage changes>
          blob-dir .../sample-buildout/var/demoblob
          # FileStorage database
          <filestorage>
            path .../sample-buildout/var/demofs/Data.fs
          </filestorage>
        </blobstorage>
    ...

Finally, you can add only a blob storage. Changes will then not be
persisted on disk, but blob support will be available separately (it's
not supported by the in-memory demostorage)::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... file-storage = newfs/Data.fs
    ... demo-storage = on
    ... demo-blob-storage = ${buildout:directory}/var/demoblob
    ...
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        # Main database
        cache-size 30000
    <BLANKLINE>
    # DemoStorage
        <demostorage>
    <BLANKLINE>
        # FileStorage database
        <filestorage base>
          path .../sample-buildout/var/newfs/Data.fs
        </filestorage>
    <BLANKLINE>
    <BLANKLINE>
        # Blob-enabled FileStorage database
        <blobstorage changes>
          blob-dir .../sample-buildout/var/demoblob
          <demostorage />
        </blobstorage>
    <BLANKLINE>
        </demostorage>
        mount-point /
    </zodb_db>
    ...


ZlibStorage
===========

To have a ZlibStorage configuration, you can use zlib-storage::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... file-storage = newfs/Data.fs
    ... zlib-storage = active
    ...
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        # Main database
        cache-size 30000
    <BLANKLINE>
    # Blob-enabled FileStorage database
        <blobstorage>
          blob-dir .../sample-buildout/var/blobstorage
    <BLANKLINE>
          %import zc.zlibstorage
          # ZlibStorage wrapper
          <zlibstorage>
            compress true
    <BLANKLINE>
            # FileStorage database
            <filestorage>
              path .../sample-buildout/var/newfs/Data.fs
            </filestorage>
    <BLANKLINE>
          </zlibstorage>
    <BLANKLINE>
        </blobstorage>
        mount-point /
    </zodb_db>
    ...
    <BLANKLINE>

To have a ZlibStorage configuration with no active compression, you
can set the ``zlib-storage`` option to 'passive'::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... file-storage = newfs/Data.fs
    ... zlib-storage = passive
    ...
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        # Main database
        cache-size 30000
    <BLANKLINE>
    # Blob-enabled FileStorage database
        <blobstorage>
          blob-dir .../sample-buildout/var/blobstorage
    <BLANKLINE>
          %import zc.zlibstorage
          # ZlibStorage wrapper
          <zlibstorage>
            compress false
    <BLANKLINE>
            # FileStorage database
            <filestorage>
              path .../sample-buildout/var/newfs/Data.fs
            </filestorage>
    <BLANKLINE>
          </zlibstorage>
    <BLANKLINE>
        </blobstorage>
        mount-point /
    </zodb_db>
    ...
    <BLANKLINE>


BeforeStorage
=============

To have a BeforeStorage configuration, you can use before-storage::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... file-storage = newfs/Data.fs
    ... before-storage = now
    ...
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        # Main database
        cache-size 30000
    <BLANKLINE>
    %import zc.beforestorage
        # BeforeStorage
        <before>
          before now
    <BLANKLINE>
          # Blob-enabled FileStorage database
          <blobstorage>
            blob-dir .../sample-buildout/var/blobstorage
            # FileStorage database
            <filestorage>
              path .../sample-buildout/var/newfs/Data.fs
            </filestorage>
          </blobstorage>
    <BLANKLINE>
        </before>
        mount-point /
    </zodb_db>
    ...
    <BLANKLINE>

The before-storage option can be combined with a demo-storage::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... file-storage = newfs/Data.fs
    ... before-storage = now
    ... demo-storage = on
    ...
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        # Main database
        cache-size 30000
    <BLANKLINE>
        # DemoStorage
        <demostorage>
    <BLANKLINE>
        %import zc.beforestorage
        # BeforeStorage
        <before>
          before now
    <BLANKLINE>
          # Blob-enabled FileStorage database
          <blobstorage>
            blob-dir .../sample-buildout/var/blobstorage
            # FileStorage database
            <filestorage>
              path .../sample-buildout/var/newfs/Data.fs
            </filestorage>
          </blobstorage>
    <BLANKLINE>
        </before>
    <BLANKLINE>
    <BLANKLINE>
        </demostorage>
        mount-point /
    </zodb_db>
    ...
    <BLANKLINE>

BlobStorage
===========

To have a BlobStorage configuration, you can use blob-storage::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... blob-storage = ${buildout:directory}/var/blob
    ...
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        # Main database
        cache-size 30000
        # Blob-enabled FileStorage database
        <blobstorage>
          blob-dir .../sample-buildout/var/blob
          # FileStorage database
          <filestorage>
            path .../sample-buildout/var/filestorage/Data.fs
          </filestorage>
        </blobstorage>
        mount-point /
    </zodb_db>
    ...
    <BLANKLINE>


RelStorage
==========

To have a RelStorage configuration, you can use rel-storage::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... rel-storage =
    ...   type postgresql
    ...   dbname zodb
    ...   user tarek
    ...   host example.com
    ...   password secret space
    ...   keep-history false
    ...
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        # Main database
        cache-size 30000
    %import relstorage
        <relstorage>
            keep-history false
            <postgresql>
                dsn dbname='zodb' user='tarek' host='example.com' password='secret space'
            </postgresql>
        </relstorage>
        mount-point /
    </zodb_db>
    ...
    <BLANKLINE>

ZEO storage
===========

If you want to connect to a zeo server you specify some additional properties
for the plone.recipe.zope2instance recipe.

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... zeo-client = yes
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        ...
        <zeoclient>
            read-only false
            read-only-fallback false
            blob-dir .../sample-buildout/var/blobcache
            shared-blob-dir no
            server 8100
            storage 1
            name zeostorage
            var .../sample-buildout/parts/instance/var
            cache-size 128MB
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
        </zeoclient>
        ...
    </zodb_db>
    ...
    <BLANKLINE>

If `zeo-client-client` and other relevant ZEO options such as 
`zeo-client-blob-cache-size` and `zeo-client-blob-cache-size-check` are 
specified, they should get included in that section as well.

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... zeo-client = yes
    ... zeo-client-client = persistentcache88
    ... min-disconnect-poll = 10
    ... max-disconnect-poll = 20
    ... zeo-client-blob-cache-size = 5GB
    ... zeo-client-blob-cache-size-check = 50
    ... zeo-client-read-only-fallback = true
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        ...
        <zeoclient>
            read-only false
            read-only-fallback true
            blob-dir .../sample-buildout/var/blobcache
            shared-blob-dir no
            server 8100
            storage 1
            name zeostorage
            var .../sample-buildout/parts/instance/var
            cache-size 128MB
            blob-cache-size 5GB
            blob-cache-size-check 50
    <BLANKLINE>
            client persistentcache88
            min-disconnect-poll 10
            max-disconnect-poll 20
        </zeoclient>
        ...
    </zodb_db>
    ...
    <BLANKLINE>

Verify that demo-storage is correctly applied

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... zeo-client = yes
    ... demo-storage = yes
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        ...
        # DemoStorage
        <demostorage>
        # ZEOStorage database
        <zeoclient>
            read-only false
            read-only-fallback false
            server 8100
            storage 1
            name zeostorage
            var .../sample-buildout/parts/instance/var
            cache-size 128MB
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
        </zeoclient>
        </demostorage>
        ...
    </zodb_db>
    ...
    <BLANKLINE>

Verify that blob-storage is correctly applied

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... zeo-client = yes
    ... blob-storage = ${buildout:directory}/var/blob
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        ...
    # Blob-enabled ZEOStorage database
        <zeoclient>
          read-only false
          read-only-fallback false
          blob-dir .../sample-buildout/var/blob
          shared-blob-dir no
          server 8100
          storage 1
          name zeostorage
          var .../sample-buildout/parts/instance/var
          cache-size 128MB
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
        </zeoclient>
        ...
    </zodb_db>
    ...
    <BLANKLINE>

Verify that demo-storage is correctly applied together with
before-storage::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... zeo-client = yes
    ... demo-storage = yes
    ... before-storage = now
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        # Main database
        cache-size 30000
    <BLANKLINE>
    # DemoStorage
        <demostorage>
    <BLANKLINE>
        %import zc.beforestorage
        # BeforeStorage
        <before>
          before now
        # Blob-enabled ZEOStorage database
          <zeoclient>
            read-only false
            read-only-fallback false
            blob-dir .../sample-buildout/var/blobcache
            shared-blob-dir no
            server 8100
            storage 1
            name zeostorage
            var .../sample-buildout/parts/instance/var
            cache-size 128MB
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
          </zeoclient>
        </before>
    <BLANKLINE>
        </demostorage>
        mount-point /
    </zodb_db>
    ...
    <BLANKLINE>

You can get specific zeo server address using `zeo-address`.

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... zeo-client = yes
    ... zeo-address = 127.0.0.1:8101
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        ...
        <zeoclient>
            read-only false
            read-only-fallback false
            blob-dir .../sample-buildout/var/blobcache
            shared-blob-dir no
            server 127.0.0.1:8101
            storage 1
            name zeostorage
            var .../sample-buildout/parts/instance/var
            cache-size 128MB
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
        </zeoclient>
        ...
    </zodb_db>
    ...
    <BLANKLINE>

You can also set multiple zeo server addresses using `zeo-address`.

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... zeo-client = yes
    ... zeo-address = 127.0.0.1:8101 127.0.0.1:8102
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with a basic zope.conf::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <zodb_db main>
        ...
        <zeoclient>
            read-only false
            read-only-fallback false
            blob-dir .../sample-buildout/var/blobcache
            shared-blob-dir no
            server 127.0.0.1:8101
            server 127.0.0.1:8102
            storage 1
            name zeostorage
            var .../sample-buildout/parts/instance/var
            cache-size 128MB
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
    <BLANKLINE>
        </zeoclient>
        ...
    </zodb_db>
    ...
    <BLANKLINE>

Custom Event log
================

`event-log-custom` is a new option that allows you to create
a custom event log section. For example, let's say you want
to use `rotatezlogs`::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ...
    ... event-log-custom =
    ...     %%import iw.rotatezlogs
    ...     <rotatelogfile>
    ...         path %(sample_buildout)s/var/log/event.log
    ...         max-bytes 1MB
    ...         backup-count 5
    ...     </rotatelogfile>
    ...
    ... event-log-level = info
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with the custom event log::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <eventlog>
      level info
      %import iw.rotatezlogs
      <rotatelogfile>
        path .../sample-buildout/var/log/event.log
        max-bytes 1MB
        backup-count 5
      </rotatelogfile>
    </eventlog>
    ...
    <BLANKLINE>


Mailing logger
==============

`mailinglogger` allows you to configure mail actions for the event log::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ...
    ... mailinglogger =
    ...     <mailing-logger>
    ...       level error
    ...       flood-level 10
    ...       smtp-server smtp.mydomain.com
    ...       from logger@mydomain.com
    ...       to errors@mydomain.com
    ...       subject [My domain error]
    ...     </mailing-logger>
    ...
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with the mailing logger::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    %import mailinglogger
    <eventlog>
      <mailing-logger>
        level error
        flood-level 10
        smtp-server smtp.mydomain.com
        from logger@mydomain.com
        to errors@mydomain.com
        subject [My domain error]
      </mailing-logger>
      level INFO
    ...
    </eventlog>
    ...
    <BLANKLINE>


Custom access log
=================

`access-log-custom` is a new option that allows you to create
a custom event log section. For example, let's say you want
to use `rotatezlogs`::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ...
    ... access-log-custom =
    ...     %%import iw.rotatezlogs
    ...     <rotatelogfile>
    ...         path %(sample_buildout)s/var/log/event.log
    ...         max-bytes 1MB
    ...         backup-count 5
    ...     </rotatelogfile>
    ...
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance, with the custom event log::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <logger access>
      level WARN
      %import iw.rotatezlogs
      <rotatelogfile>
        path .../sample-buildout/var/log/event.log
        max-bytes 1MB
        backup-count 5
      </rotatelogfile>
    </logger>
    ...
    <BLANKLINE>

Custom site.zcml file
=====================

`site-zcml` is a new option that allows you to create a custom site.zcml file.
When this option is used the `zcml` option is ignored. Let's try it::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... # the zcml option will be ignored when a site-zcml option is given
    ... zcml =
    ...       test.example
    ...
    ... site-zcml =
    ...       <configure xmlns="http://namespaces.zope.org/zope"
    ...                  xmlns:five="http://namespaces.zope.org/five">
    ...           <include package="Products.Five" />
    ...           <meta:redefinePermission from="zope2.Public" to="zope.Public" />
    ...           <include package="test.example" />
    ...       </configure>
    ...
    ... ''' % options)

Let's run the buildout::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

Now let's check that we have a zope instance, with the custom site.zcml::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> print open(os.path.join(instance, 'etc', 'site.zcml')).read()
    <configure xmlns="http://namespaces.zope.org/zope"
               xmlns:five="http://namespaces.zope.org/five">
        <include package="Products.Five" />
        <meta:redefinePermission from="zope2.Public" to="zope.Public" />
        <include package="test.example" />
    </configure>
    <BLANKLINE>


Environment Variables
=====================

We can specify environment variables for Zope.  Sometimes it is
useful to set the TZ variable if our instance will be moving
between several servers::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... environment-vars = TZ US/Eastern
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

Our environment variables should be set now::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <environment>
      TZ US/Eastern
    </environment>
    ...

Now let's add several environment variables::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... environment-vars =
    ...     TZ US/Eastern
    ...     TMP /var/tmp
    ...     DISABLE_PTS True
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

Our environment variables should be set now::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> import re
    >>> env_vars = re.compile(r"<environment>\n\s*(?P<vars>.*)\n</environment>", re.M | re.S)
    >>> re.search(env_vars, zope_conf).group('vars')
    'TZ US/Eastern\nTMP /var/tmp\nDISABLE_PTS True'

Several all on one line::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... environment-vars = TZ US/Eastern TMP /var/tmp DISABLE_PTS True
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

Our environment variables should be set now::

    >>> instance = os.path.join(sample_buildout, 'parts', 'instance')
    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> re.search(env_vars, zope_conf).group('vars')
    'TZ US/Eastern\nTMP /var/tmp\nDISABLE_PTS True'


HTTP server
===========

Check additional options to the HTTP server::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... http-force-connection-close = on
    ... http-fast-listen = off
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

And check it::

    >>> zope_conf = open(os.path.join(instance, 'etc', 'zope.conf')).read()
    >>> zope_conf = zope_conf.replace('\\', '/')
    >>> print zope_conf
    %define INSTANCEHOME .../sample-buildout/parts/instance
    ...
    <http-server>
      address 8080
      force-connection-close on
      # Set to off to defer opening of the HTTP socket until the end of the
      # startup phase:
      fast-listen off
    <BLANKLINE>
    </http-server>
    ...

Edge Cases
==========

Some Linux distributions of Zope2 don't have the windows scripts.
Let's run a minimal buildout without them to make sure
we don't error::

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

Relative paths in scripts
=========================

The recipe supports the generation of scripts with relative paths.

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... relative-paths = true
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... ''' % options)
    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

Our generated script now has a reference to the relative path.

    >>> import sys
    >>> 

    >>> instance_path = join('bin', 'instance')
    >>> if WINDOWS:
    ...     instance_path += '-script.py'
    >>> open(instance_path).read()
    "...base = ...__file__..."

Custom Zope Conf
=================

`zope-conf` is an option that allows you to use a specific Zope config file.

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... zope-conf = /some/path/my.conf
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should have a zope instance script with the custom config file::

    >>> instance_path = join('bin', 'instance')
    >>> if WINDOWS:
    ...     instance_path += '-script.py'
    >>> open(instance_path).read()
    "...plone.recipe.zope2instance.ctl.main(...['-C', '/some/path/my.conf']..."


Resources directory
===================

`resources` is an option that allows you to register a
plone.app.theming resources directory.

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... resources = ${buildout:directory}/myresources
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

The directory should have been generated, and zope config created::

    >>> 'myresources' in os.listdir(os.curdir)
    True
    >>> includes_path = join('parts', 'instance', 'etc', 'package-includes')
    >>> ls(includes_path)
    -  998-resources-configure.zcml
    >>> cat(includes_path, '998-resources-configure.zcml')
    <configure xmlns="http://namespaces.zope.org/zope"
               xmlns:plone="http://namespaces.plone.org/plone">
        <include package="plone.resource" file="meta.zcml"/>
        <plone:static directory=".../sample-buildout/myresources"/>
    </configure>


Locales directory
===================

`locales` is an option that allows you to register a
plone.app.theming locales directory.

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... locales = ${buildout:directory}/mylocales
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

The directory should have been generated, and zope config created::

    >>> 'mylocales' in os.listdir(os.curdir)
    True
    >>> includes_path = join('parts', 'instance', 'etc', 'package-includes')
    >>> ls(includes_path)
    -  001-locales-configure.zcml
    >>> cat(includes_path, '001-locales-configure.zcml')
    <configure xmlns="http://namespaces.zope.org/zope"
               xmlns:i18n="http://namespaces.zope.org/i18n">
        <i18n:registerTranslations directory=".../sample-buildout/mylocales" />
    </configure>


Initialization
==============

`initialization` is an option that allows you to add custom Python
code to the initialization process. 

    >>> write('buildout.cfg',
    ... '''
    ... [buildout]
    ... parts = instance
    ... find-links = %(sample_buildout)s/eggs
    ...
    ... [instance]
    ... recipe = plone.recipe.zope2instance
    ... eggs =
    ... user = me:me
    ... initialization = 
    ...     print 'Initialization complete!' 
    ... ''' % options)

Let's run it::

    >>> print system(join('bin', 'buildout')),
    Uninstalling instance.
    Installing instance.
    Generated script '...instance'.
    Generated interpreter '.../parts/instance/bin/interpreter'.

We should see the given initialization commands included in the instance
script::

    >>> instance = open(os.path.join(sample_buildout, 'bin', 'instance')).read()
    >>> "print 'Initialization complete!'" in instance
    True

