Deploying Plone 2 with a ZEO Server

At Mooball, there are still instances running with a CMFPlone v. 2. Very, very old. Back in the days when Plone v2 was shipped, Python 2.3 was hip and zc.buildout was never heard of.
One motivation I have to deploy with a ZEO is the possibility to pack your database from a simple cron script (which you configure in your buildout too). If you’re still one of them who has to deal with these old instances, here is what you do:

Use Python 2.3

I’ve always compiled my own python 2.3 to avoid any side effects introduced by python installations from the distribution. Version 1.2.1 of zc.buildout works fine for me, the only missing thing is the subprocess module introduced in python 2.4. To get buildout running, I’ve copied from python 2.4 into the python 2.3 installation. After that is done, run the bootstrap with (the -v pins the zc.buildout version to 1.2.1):

/path/to/python2.3/bin/python -v1.2.1

Run with zc.buildout

I’ve created a sample buildout.cfg and put it up on gist. The important part is the ‘fixup’ which simply comments out 3 keys in the generated config files, which are not supported by the Zope/ZEO version. Depending how much time you have available, play with the options to pin eggs instead of dropping the whole CMFPlone tarball in the products directory. Running the buildout from the products directory is the quickest way tho.

ZODB/ZEO Error Masking Wrong Filesystem Permissions

One of the clients staging instances showed quite a few tracebacks of that type:

Traceback (innermost last):
  Module zope.contentprovider.tales, line 77, in __call__
  Module zope.viewlet.manager, line 112, in update
  Module zope.viewlet.manager, line 118, in _updateViewlets
  Module my.product.viewlets.industry, line 29, in update
  Module Products.ZCatalog.Lazy, line 190, in __getitem__
  Module Products.ZCatalog.Catalog, line 121, in __getitem__
  Module ZODB.Connection, line 860, in setstate
  Module ZODB.Connection, line 901, in _setstate
  Module ZEO.ClientStorage, line 815, in load
  Module ZEO.cache, line 143, in call
  Module ZEO.cache, line 494, in load
  Module ZODB.fsIndex, line 125, in get
TypeError: mybrains.__cmp__(x,y) requires y to be a 'mybrains', not a 'NoneType'

I’m getting to the point, since it had something to do with the deployment. Some packages were deployed as develop eggs on the instance. Only a few files were created with the wrong filesystem permissions, so neither Zope nor ZEO were able to access them. After changing the permissions the errors were gone. So be sure to check all filesystem permissions and if the processes have access to them. If that doesn’t solve it, be sure to also check if not your database is corrupt.

z3c.autoinclude does not automatically include a plone package

Something I stumbled over just recently and is a PEBKAC again. What happens if you create a plone package and you always need to explicitly specify the zcml slot for that package? Check the namespace declaration in the That means, what I had configured:

 # -*- Entry points: -*-
 target = plone

But the packages layout was “mooball.portlets.latestcontent”. After digging, I found out that simply the namespace_package is incorrectly declared. Changing it to:

 namespace_packages=['mooball', 'mooball.portlets'],
 # -*- Entry points: -*-
 target = plone

… got it correctly included via z3c.autoinclude.

No such file or directory FakePlugin.egg-info

In case you run into a similar issue which ends up in a traceback like this:

ZopeXMLConfigurationError: File "/opt/works/projects/plone4/nuw.types/nuw/types/configure.zcml", line 12.2-12.37
ZopeXMLConfigurationError: File "/home/roman/.buildout/eggs/mooball.plone.activecampaign-0.2-py2.7.egg/mooball/plone/activecampaign/configure.zcml", line 10.2-10.37
OSError: [Errno 2] No such file or directory: '/home/roman/tools/python2.7/lib/python2.7/site-packages/tests/fake_packages/FakePlugin.egg/FakePlugin.egg-info'

you might have made the same mistake then I did: install ZopeSkel in your (system-) python installation. Never do this. Mikko explains on his blog why.

So, check your python installation and uninstall/remove the PasteScript.

handleUidAnnotationEvent from Products.CMFUID throws AttributeError

I stumbled over a weird error during a package setup, which turned out a PEBCAC error. The full traceback:

File "/home/roman/.buildout/eggs/zope.interface-3.6.3-py2.6-linux-x86_64.egg/zope/interface/", line 583, in subscribers
File "/home/roman/.buildout/eggs/Products.CMFUid-2.2.1-py2.6.egg/Products/CMFUid/", line 86, in handleUidAnnotationEvent
AttributeError: 'NoneType' object has no attribute 'unregister'

I went throught my whole code and type setup unable to find the mistake I’ve made unless I saw the problem. I imported a configuration module for an ArcheTypes content type declaration from a separate package which was not declared in the of my new package, e.g.:

$ cat
from separate.package.config import PROJECTNAME
from plone.directives.form import Schema

class IMyType(Schema): ...

If you stumble over this error, make sure your imports are sane.

Broken (Arche-)Type Installation in Tests

I’ve recently run into this issue, migrating some of the Plone 3 product code to Plone 4. Installing some of the old types in my tests ended in a

File "/projects/plone3/my.product/my/product/tests/", line 19, in test_mycontent
self.portal.invokeFactory('GalleryFolder', 'spam', title='eggs')
File "/home/roman/.buildout/eggs/Products.CMFCore-2.2.4-py2.6.egg/Products/CMFCore/", line 311, in constructInstance
raise AccessControl_Unauthorized('Cannot create %s' % self.getId())
Unauthorized: Cannot create GalleryFolder

Digging deeper I found out, that all of the product factories were gone. Any debugging finding the cause of this ended up in a nowhere, until I stumbled over some odd behavior. All my imports in the are sorted, e.g.:

from Products.CMFPlone.tests.utils import MockMailHost
from Products.MailHost.interfaces import IMailHost
from Products.SiteErrorLog.SiteErrorLog import SiteErrorLog
import zope.component

What I now found out by accident is, if you move the import of the MockMailHost to the end of the import block, your Archetypes types are installable again:

from Products.MailHost.interfaces import IMailHost
from Products.SiteErrorLog.SiteErrorLog import SiteErrorLog
import zope.component
from Products.CMFPlone.tests.utils import MockMailHost

I currently don’t know why, but if anyone had the time to check, I’d be happy to know.

AttributeError when Installing Custom Theme Package

If you’re creating a new Plone theme package based on and run into the following error:

Traceback (innermost last):
  Module ZPublisher.Publish, line 126, in publish
  Module ZPublisher.mapply, line 77, in mapply
  Module ZPublisher.Publish, line 46, in call_object
  Module Products.CMFQuickInstallerTool.QuickInstallerTool, line 575, in installProducts
  Module Products.CMFQuickInstallerTool.QuickInstallerTool, line 512, in installProduct
   - __traceback_info__: ('',)
  Module Products.GenericSetup.tool, line 323, in runAllImportStepsFromProfile
   - __traceback_info__:
  Module Products.GenericSetup.tool, line 1080, in _runImportStepsFromContext
  Module Products.GenericSetup.tool, line 994, in _doRunImportStep
   - __traceback_info__:
  Module, line 40, in importTheme
  Module, line 427, in applyTheme
  Module plone.registry.recordsproxy, line 43, in __setattr__
AttributeError: currentTheme

This will probably have nothing to do with a wrong setup in your theme, but simply a dependency issue to diazo.
Just make sure you install “Diazo theme support” before your theme is installed.


Plone ConfigurationError hides missing configuration files

This one is a quicky. If you run into the following error:

    raise ConfigurationError("Unknown directive", ns, n)
zope.configuration.xmlconfig.ZopeXMLConfigurationError: File "/opt/works/projects/plone4/apf.buildout/parts/instance/etc/site.zcml", line 16.2-16.23
ZopeXMLConfigurationError: File "/home/roman/.buildout/eggs/Products.CMFPlone-4.1-py2.6.egg/Products/CMFPlone/configure.zcml", line 99.4-103.10
ZopeXMLConfigurationError: File "/home/roman/.buildout/eggs/", line 16.4-16.52
ZopeXMLConfigurationError: File "/home/roman/.buildout/eggs/plone.directives.dexterity-1.0.2-py2.6.egg/plone/directives/dexterity/configure.zcml", line 3.4-3.35
ZopeXMLConfigurationError: File "/home/roman/.buildout/eggs/five.grok-1.2.0-py2.6.egg/five/grok/configure.zcml", line 15.2-15.40
ZopeXMLConfigurationError: File "/home/roman/.buildout/eggs/grokcore.viewlet-1.8-py2.6.egg/grokcore/viewlet/configure.zcml", line 7.2-7.44
ZopeXMLConfigurationError: File "/home/roman/.buildout/eggs/zope.contentprovider-3.7.2-py2.6.egg/zope/contentprovider/configure.zcml", line 12.4
ConfigurationError: ('Unknown directive', u'', u'expressiontype')

… and you are using and dexterity you will want to
check your buildout configuration file.
Make sure you have the dependent configuration files included:

extends =

The above configurations can change with future plone releases.

Plone Attribute Error DirContainedFileResource

This is a short one.

In case you’re running in an error on your Plone site which looks similar to this:

File "[...]/eggs/Products.ResourceRegistries-2.0.3-py2.6.egg/Products/ResourceRegistries/browser/", line 27, in scripts
 content = registry.getInlineResource(script.getId(), context)
 File "[...]/eggs/Products.ResourceRegistries-2.0.3-py2.6.egg/Products/ResourceRegistries/tools/", line 840, in getInlineResource
 output = self.getResourceContent(item, context)
 File "[...]/eggs/Products.ResourceRegistries-2.0.3-py2.6.egg/Products/ResourceRegistries/tools/", line 246, in getResourceContent
 output = BaseRegistryTool.getResourceContent(self, item, context, original)
 File "[...]/eggs/Products.ResourceRegistries-2.0.3-py2.6.egg/Products/ResourceRegistries/tools/", line 589, in getResourceContent
 method = obj.browserDefault(self.REQUEST)[0].__name__
 File "[...]/eggs/zope.browserresource-3.10.3-py2.6.egg/zope/browserresource/", line 94, in browserDefault
 return getattr(self, request.method), ()
 AttributeError: 'DirContainedFileResource7' object has no attribute 'POST'

Check if some of your javascripts have inline rendering enabled and obviously disable it. This seems to be more like a work around rather than a fix. Haven’t had time to investigate what was really going wrong there. Any additional pointers welcome!

If acquisition comes in the way

I’ve witnessed a very strange error today.

The problem

I had a custom content-type which was partly indexed. When viewing the content type, parts of the edit form showed raw HTML code instead of widgets:

What was going on?

The solution

I hunted around for a while but checked the contents of the index. Strangely, it had a whole page indexed. After investigating further: it’s another object in the portal with the same id as the attribute on the content-type. The error happens only, if the attribute is missing on the content-type and an object in the hirarchy above has the name id.

So – if you encounter a problem like this, check if the portal_catalog may grab a different object for indexing with the same name of your attribute.