========================= 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 debug-mode off security-policy-implementation C verbose-security off default-zpublisher-encoding utf-8 http-header-max-length 8192 zserver-threads 2 level INFO path .../sample-buildout/var/log/instance.log level INFO level WARN path .../sample-buildout/var/log/instance-Z2.log format %(message)s address 8080 # Main database cache-size 30000 # Blob-enabled FileStorage database blob-dir .../sample-buildout/var/blobstorage # FileStorage database path .../sample-buildout/var/filestorage/Data.fs mount-point / # Temporary storage database (for sessions) name temporary storage for sessioning mount-point /temp_folder container-class Products.TemporaryFolder.TemporaryContainer pid-filename .../sample-buildout/var/instance.pid lock-filename .../sample-buildout/var/instance.lock python-check-interval 1000 enable-product-installation off 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 ... # valid key is "address" address 8021 ... 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 ... address 1980 force-connection-close off ... 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 ... address 1980 force-connection-close on ... 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 ... # Main database cache-size 30000 # DemoStorage # FileStorage database path .../sample-buildout/var/newfs/Data.fs mount-point / ... 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 ... # Main database cache-size 30000 # Blob-enabled FileStorage database blob-dir .../sample-buildout/var/blobstorage # FileStorage database path .../sample-buildout/var/newfs/Data.fs mount-point / ... 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 ... # Main database cache-size 30000 # DemoStorage # FileStorage database path .../sample-buildout/var/newfs/Data.fs # FileStorage database path .../sample-buildout/var/demofs/Data.fs mount-point / ... 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 ... blob-dir .../sample-buildout/var/blob # FileStorage database path .../sample-buildout/var/newfs/Data.fs ... blob-dir .../sample-buildout/var/demoblob # FileStorage database path .../sample-buildout/var/demofs/Data.fs ... 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 ... # Main database cache-size 30000 # DemoStorage # FileStorage database path .../sample-buildout/var/newfs/Data.fs # Blob-enabled FileStorage database blob-dir .../sample-buildout/var/demoblob mount-point / ... 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 ... # Main database cache-size 30000 # Blob-enabled FileStorage database blob-dir .../sample-buildout/var/blobstorage %import zc.zlibstorage # ZlibStorage wrapper compress true # FileStorage database path .../sample-buildout/var/newfs/Data.fs mount-point / ... 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 ... # Main database cache-size 30000 # Blob-enabled FileStorage database blob-dir .../sample-buildout/var/blobstorage %import zc.zlibstorage # ZlibStorage wrapper compress false # FileStorage database path .../sample-buildout/var/newfs/Data.fs mount-point / ... 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 ... # Main database cache-size 30000 %import zc.beforestorage # BeforeStorage before now # Blob-enabled FileStorage database blob-dir .../sample-buildout/var/blobstorage # FileStorage database path .../sample-buildout/var/newfs/Data.fs mount-point / ... 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 ... # Main database cache-size 30000 # DemoStorage %import zc.beforestorage # BeforeStorage before now # Blob-enabled FileStorage database blob-dir .../sample-buildout/var/blobstorage # FileStorage database path .../sample-buildout/var/newfs/Data.fs mount-point / ... 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 ... # Main database cache-size 30000 # Blob-enabled FileStorage database blob-dir .../sample-buildout/var/blob # FileStorage database path .../sample-buildout/var/filestorage/Data.fs mount-point / ... 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 ... # Main database cache-size 30000 %import relstorage keep-history false dsn dbname='zodb' user='tarek' host='example.com' password='secret space' mount-point / ... 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 ... ... 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 ... ... 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 ... ... 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 client persistentcache88 min-disconnect-poll 10 max-disconnect-poll 20 ... ... 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 ... ... # DemoStorage # ZEOStorage database read-only false read-only-fallback false server 8100 storage 1 name zeostorage var .../sample-buildout/parts/instance/var cache-size 128MB ... ... 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 ... ... # Blob-enabled ZEOStorage database 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 ... ... 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 ... # Main database cache-size 30000 # DemoStorage %import zc.beforestorage # BeforeStorage before now # Blob-enabled ZEOStorage database 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 mount-point / ... 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 ... ... 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 ... ... 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 ... ... 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 ... ... 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 ... ... path %(sample_buildout)s/var/log/event.log ... max-bytes 1MB ... backup-count 5 ... ... ... 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 ... level info %import iw.rotatezlogs path .../sample-buildout/var/log/event.log max-bytes 1MB backup-count 5 ... 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 = ... ... level error ... flood-level 10 ... smtp-server smtp.mydomain.com ... from logger@mydomain.com ... to errors@mydomain.com ... subject [My domain error] ... ... ... ''' % 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 level error flood-level 10 smtp-server smtp.mydomain.com from logger@mydomain.com to errors@mydomain.com subject [My domain error] level INFO ... ... 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 ... ... path %(sample_buildout)s/var/log/event.log ... max-bytes 1MB ... backup-count 5 ... ... ... ''' % 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 ... level WARN %import iw.rotatezlogs path .../sample-buildout/var/log/event.log max-bytes 1MB backup-count 5 ... Disable access log ================== If we assign `disable` to `z2-log`, the whole section will be omitted:: >>> write('buildout.cfg', ... ''' ... [buildout] ... parts = instance ... find-links = %(sample_buildout)s/eggs ... ... [instance] ... recipe = plone.recipe.zope2instance ... eggs = ... user = me:me ... ... z2-log = disable ... ''' % 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 no access 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('\\', '/') >>> "logger access" in zope_conf False >>> "eventlog" in zope_conf True Disable events log ================== If we assign `disable` to `event-log`, the whole section will be omitted:: >>> write('buildout.cfg', ... ''' ... [buildout] ... parts = instance ... find-links = %(sample_buildout)s/eggs ... ... [instance] ... recipe = plone.recipe.zope2instance ... eggs = ... user = me:me ... ... event-log = disable ... ''' % 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 no access 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('\\', '/') >>> "logger access" in zope_conf True >>> "eventlog" in zope_conf False 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 = ... ... ... ... ... ... ... ''' % 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() 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 ... TZ US/Eastern ... 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"\n\s*(?P.*)\n", 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 ... 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 ... 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']..." Custom Zope Conf Imports ======================== `zope-conf-imports` is an option that allows you to import python packages that define custom zope.conf sections using ZConfig API. >>> write('buildout.cfg', ... ''' ... [buildout] ... parts = instance ... find-links = %(sample_buildout)s/eggs ... ... [instance] ... recipe = plone.recipe.zope2instance ... eggs = ... user = me:me ... zope-conf-imports = ... mailinglogger ... eea.graylogger ... ''' % 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 custom imports:: >>> 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 %import mailinglogger %import eea.graylogger %define INSTANCEHOME .../sample-buildout/parts/instance ... 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') 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') 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