Failed to update Plone from 5.1 to 5.2

Hello everyone,
I am recently working on updating a Plone website from 5.1 to 5.2. I was able to re-write the buildout and make it run without any problem. But the @@plone_update module fails to update the website. I think the issue is caused by the add-ons, and it keeps giving errors for another add-on if I delete the one in the error message. Has anyone seen this before or has any suggestion on how to fix this issue.

  • Plone 5.2.12
  • Zope 4.8.7
  • Python 2.7.15rc

The error message:
Traceback (most recent call last):
File "/var/www/zm/buildout-cache/eggs/Products.CMFPlone-5.2.12-py2.7.egg/Products/CMFPlone/MigrationTool.py", line 292, in upgrade
step['step'].doStep(setup)
File "/var/www/zm/buildout-cache/eggs/Products.GenericSetup-2.3.0-py2.7.egg/Products/GenericSetup/upgrade.py", line 185, in doStep
self.handler(tool)
File "/var/www/zm/buildout-cache/eggs/plone.app.upgrade-2.1.5-py2.7.egg/plone/app/upgrade/v52/alphas.py", line 89, in to52alpha1
loadMigrationProfile(context, 'profile-plone.app.upgrade.v52:to52alpha1')
File "/var/www/zm/buildout-cache/eggs/plone.app.upgrade-2.1.5-py2.7.egg/plone/app/upgrade/utils.py", line 203, in loadMigrationProfile
context.runAllImportStepsFromProfile(profile, purge_old=False)
File "/var/www/zm/buildout-cache/eggs/Products.GenericSetup-2.3.0-py2.7.egg/Products/GenericSetup/tool.py", line 405, in runAllImportStepsFromProfile
dependency_strategy=dependency_strategy)
File "/var/www/zm/buildout-cache/eggs/Products.GenericSetup-2.3.0-py2.7.egg/Products/GenericSetup/tool.py", line 1511, in _runImportStepsFromContext
message = self._doRunImportStep(step, context)
File "/var/www/zm/buildout-cache/eggs/Products.GenericSetup-2.3.0-py2.7.egg/Products/GenericSetup/tool.py", line 1323, in _doRunImportStep
return handler(context)
File "/var/www/zm/buildout-cache/eggs/Products.CMFPlone-5.2.12-py2.7.egg/Products/CMFPlone/resources/exportimport/bundles.py", line 34, in combine
combine_bundles(site)
File "/var/www/zm/buildout-cache/eggs/Products.CMFPlone-5.2.12-py2.7.egg/Products/CMFPlone/resources/browser/combine.py", line 180, in combine_bundles
write_js(context, production_folder, 'default')
File "/var/www/zm/buildout-cache/eggs/Products.CMFPlone-5.2.12-py2.7.egg/Products/CMFPlone/resources/browser/combine.py", line 120, in write_js
folder.writeFile(meta_bundle + '.js', fi)
File "/var/www/zm/buildout-cache/eggs/plone.resource-2.1.4-py2.7.egg/plone/resource/directory.py", line 163, in writeFile
f = File(filename, filename, data)
File "/var/www/zm/buildout-cache/eggs/Zope-4.8.7-py2.7.egg/OFS/Image.py", line 159, in init
data, size = self._read_data(file)
File "/var/www/zm/buildout-cache/eggs/Zope-4.8.7-py2.7.egg/OFS/Image.py", line 636, in _read_data
transaction.savepoint(optimistic=True)
File "/var/www/zm/buildout-cache/eggs/transaction-3.0.1-py2.7.egg/transaction/_manager.py", line 272, in savepoint
return self.manager.savepoint(optimistic)
File "/var/www/zm/buildout-cache/eggs/transaction-3.0.1-py2.7.egg/transaction/_manager.py", line 150, in savepoint
return self.get().savepoint(optimistic)
File "/var/www/zm/buildout-cache/eggs/transaction-3.0.1-py2.7.egg/transaction/_transaction.py", line 228, in savepoint
self._saveAndRaiseCommitishError() # reraises!
File "/var/www/zm/buildout-cache/eggs/transaction-3.0.1-py2.7.egg/transaction/_transaction.py", line 316, in _saveAndRaiseCommitishError
reraise(t, v, tb)
File "/var/www/zm/buildout-cache/eggs/transaction-3.0.1-py2.7.egg/transaction/_transaction.py", line 225, in savepoint
savepoint = Savepoint(self, optimistic, *self._resources)
File "/var/www/zm/buildout-cache/eggs/transaction-3.0.1-py2.7.egg/transaction/_transaction.py", line 626, in init
savepoint = savepoint()
File "/var/www/zm/buildout-cache/eggs/ZODB-5.8.0-py2.7.egg/ZODB/Connection.py", line 994, in savepoint
self._commit(None)
File "/var/www/zm/buildout-cache/eggs/ZODB-5.8.0-py2.7.egg/ZODB/Connection.py", line 545, in _commit
self._store_objects(ObjectWriter(obj), transaction)
File "/var/www/zm/buildout-cache/eggs/ZODB-5.8.0-py2.7.egg/ZODB/Connection.py", line 576, in _store_objects
p = writer.serialize(obj) # This calls getstate of obj
File "/var/www/zm/buildout-cache/eggs/ZODB-5.8.0-py2.7.egg/ZODB/serialize.py", line 434, in serialize
return self._dump(meta, obj.getstate())
File "/var/www/zm/buildout-cache/eggs/ZODB-5.8.0-py2.7.egg/ZODB/serialize.py", line 443, in _dump
self._p.dump(state)
PicklingError: Can't pickle <class 'bda.plone.cart.interfaces.ICartExtensionLayer'>: import of module bda.plone.cart.interfaces failed
End of upgrade path, main migration has finished.
The upgrade path did NOT reach current version.
Migration has failed

Apparently, bda.plone.cart.interfaces is missing. Try to make it available and then try again.

alternatively, if you don't use the add-on anymore: in 5.1, add bda.plone.cart to buildout if it is not already there, run buildout, uninstall it (and maybe other bda.plone add-ons) from the control panel, then copy the database to your 5.2 site.

I used collective.migrationhelpers to "fake" missing layer/utilities like its done here:

there are also other helpful methods in this package.

I think bda.plone.cart can be uninstalled before migration, it is probably better to try that approach first.

Unfortunately there's no uninstall profile in this package ... so you have to remove the Layer programatically bda.plone.cart/src/bda/plone/cart/profiles at master · bluedynamics/bda.plone.cart · GitHub

Hello Peter,
Thanks for the tip. Have one follow-up question though; do you mean I can't uninstall it from the control panel? Because I tried the Espen's tip this morning (Thank you so much Espen), and it looked like I was able to uninstall it. Now I am working on fixing other package issues, but what you wrote made me wonder if I was not able to uninstall it at all?
Also, how can I remove a layer programmatically :slight_smile: ?

There's no uninstall profile in the package, that's why you see this information in the addon controlpanel:

To remove this layer in the code you can do something like this:

from plone.browserlayer import utils

utils.unregister_layer("bda.plone.cart")

Or if you have your own upgrade profile you can create (or update) the browserlayer.xml file with this content:

<?xml version="1.0"?>
<layers>
  <layer
    name="bda.plone.cart"
    interface="bda.plone.cart.interfaces.ICartExtensionLayer" 
    remove="true" />
</layers>

but that assumes, that the package bda.plone.cart is available in the PYTHONPATH or that you've mocked the Interface like described in my first post.

Thanks so much for the detailed explanation. I will look into it.