Upgrade from 5.1.6 to 5.2.1 failed

System: CentOS7, Python: 2.7.15, Zeocluster mode

I've been trying to upgrade a 5.1.6 site to 5.2.1 this morning. I know that Plone.FormGen doesn't work properly in 5.2.1 and had replaced it on my 5.2.x sites with collective.easyform, but this site had Plone.FormGen at one point. I began by deleting all forms created with it, uninstalling it, and then removing it from the buildout, and then adding collective.easyform to the buildout, and installing that.

After that, I commented out versions.cfg in buildout.cfg, added http://dist.plone.org/release/5.2.1/versions.cfg, and updated the find-links line to point at 5.2.1 instead of 5.1.6 and ran buildout.

This resulted in a setup that would run the zinstance but not launch the clients, which returned the error: "Error: u'products' is not a known key name." Following another thread, I commented out all the 'products' lines in base.cfg and ran the buildout again.

This resulted in a setup where I could access the management tool, but attempting to get to the site upgrade page would result in a waitress error:

Internal Server Error
The server encountered an unexpected internal server error
(generated by waitress)

Again following that same thread, I modified Plone to be Plone [archetypes] in my eggs listing in buildout.cfg and re-ran buildout.

This resulted in a setup that would launch and bring me to the upgrading-the-site tool. However, attempting to run the upgrade produces the following error:

Starting the migration from version: 5116
Role / permission map imported.
Archetype tool imported.
Step pleonformgen has an invalid import handler
Ran upgrade step: Miscellaneous
Role / permission map imported.
Adapters registered.
The object None was not found, while trying to register an utility. The provided object definition was portal_syndication. The site used was: <PloneSite at /Intranet>
The object None was not found, while trying to register an utility. The provided object definition was portal_undo. The site used was: <PloneSite at /Intranet>
Utilities registered.
Skins tool imported.
Removed record plone.resources/jquery-highlightsearchterms.deps.
Removed record plone.resources/jquery-highlightsearchterms.url.
Removed record plone.resources/jquery-highlightsearchterms.js.
Removed record plone.resources/jquery-highlightsearchterms.init.
Removed record plone.resources/jquery-highlightsearchterms.export.
Removed record plone.resources/jquery-highlightsearchterms.conf.
Removed record plone.resources/jquery-highlightsearchterms.css.
Archetype tool imported.
Step pleonformgen has an invalid import handler
Rebuilding member data information. This step can take a while if your site has many users.
Ran upgrade step: Run to52alpha1 upgrade profile.
Ran upgrade step: Miscellaneous
Role / permission map imported.
Not creating required tool formgen_tool, because class Products.PloneFormGen.tools.formGenTool.FormGenTool is not found.
Not creating required tool portal_css, because class Products.ResourceRegistries.tools.CSSRegistry.CSSRegistryTool is not found.
Not creating required tool portal_javascripts, because class Products.ResourceRegistries.tools.JSRegistry.JSRegistryTool is not found.
Toolset imported.
Actions tool imported.
Control panel imported.
RepositoryTool settings imported.
Removed record plone.resources/expect.deps.
Removed record plone.resources/expect.url.
Removed record plone.resources/expect.js.
Removed record plone.resources/expect.init.
Removed record plone.resources/expect.export.
Removed record plone.resources/expect.conf.
Removed record plone.resources/expect.css.
Removed record plone.resources/js-shortcuts.deps.
Removed record plone.resources/js-shortcuts.url.
Removed record plone.resources/js-shortcuts.js.
Removed record plone.resources/js-shortcuts.init.
Removed record plone.resources/js-shortcuts.export.
Removed record plone.resources/js-shortcuts.conf.
Removed record plone.resources/js-shortcuts.css.
Removed record plone.resources/marked.deps.
Removed record plone.resources/marked.url.
Removed record plone.resources/marked.js.
Removed record plone.resources/marked.init.
Removed record plone.resources/marked.export.
Removed record plone.resources/marked.conf.
Removed record plone.resources/marked.css.
Removed record plone.resources/rjs.deps.
Removed record plone.resources/rjs.url.
Removed record plone.resources/rjs.js.
Removed record plone.resources/rjs.init.
Removed record plone.resources/rjs.export.
Removed record plone.resources/rjs.conf.
Removed record plone.resources/rjs.css.
Removed record plone.resources/react.deps.
Removed record plone.resources/react.url.
Removed record plone.resources/react.js.
Removed record plone.resources/react.init.
Removed record plone.resources/react.export.
Removed record plone.resources/react.conf.
Removed record plone.resources/react.css.
Removed record plone.resources/JSXTransformer.deps.
Removed record plone.resources/JSXTransformer.url.
Removed record plone.resources/JSXTransformer.js.
Removed record plone.resources/JSXTransformer.init.
Removed record plone.resources/JSXTransformer.export.
Removed record plone.resources/JSXTransformer.conf.
Removed record plone.resources/JSXTransformer.css.
Removed record plone.resources/sinon.deps.
Removed record plone.resources/sinon.url.
Removed record plone.resources/sinon.js.
Removed record plone.resources/sinon.init.
Removed record plone.resources/sinon.export.
Removed record plone.resources/sinon.conf.
Removed record plone.resources/sinon.css.
Archetype tool imported.
Step pleonformgen has an invalid import handler
Added BooleanIndex for field exclude_from_nav.
Indexing new indexes exclude_from_nav.
Cleaned up the toolset registry.
Upgrade aborted. Error:
Traceback (most recent call last):
  File "/vol0/local/plone/buildout-cache/eggs/Products.CMFPlone-5.2.1-py2.7.egg/Products/CMFPlone/MigrationTool.py", line 292, in upgrade
    step['step'].doStep(setup)
  File "/vol0/local/plone/buildout-cache/eggs/Products.GenericSetup-2.0.1-py2.7.egg/Products/GenericSetup/upgrade.py", line 168, in doStep
    self.handler(tool)
  File "/vol0/local/plone/buildout-cache/eggs/plone.app.upgrade-2.0.31-py2.7.egg/plone/app/upgrade/v52/betas.py", line 130, in to52beta1
    remove_interface_indexes_from_relations_catalog()
  File "/vol0/local/plone/buildout-cache/eggs/plone.app.upgrade-2.0.31-py2.7.egg/plone/app/upgrade/v52/betas.py", line 72, in remove_interface_indexes_from_relations_catalog
    if relation.from_object is not None or relation.to_object is not None:
  File "/vol0/local/plone/buildout-cache/eggs/plone.app.relationfield-2.0.1-py2.7.egg/plone/app/relationfield/monkey.py", line 13, in get_from_object
    return _object(self._from_id)
  File "/vol0/local/plone/buildout-cache/eggs/z3c.relationfield-0.9.0-py2.7.egg/z3c/relationfield/relation.py", line 126, in _object
    return intids.getObject(id)
  File "/vol0/local/plone/buildout-cache/eggs/zope.intid-4.3.0-py2.7.egg/zope/intid/__init__.py", line 85, in getObject
    return self.refs[id]()
  File "/vol0/local/plone/buildout-cache/eggs/five.intid-1.2.4-py2.7.egg/five/intid/keyreference.py", line 154, in __call__
    return self.wrapped_object
  File "/vol0/local/plone/buildout-cache/eggs/five.intid-1.2.4-py2.7.egg/five/intid/keyreference.py", line 130, in wrapped_object
    obj = traverse(self.root, self.path)
  File "/vol0/local/plone/buildout-cache/eggs/five.intid-1.2.4-py2.7.egg/five/intid/keyreference.py", line 56, in traverse
    current = current[cid]
  File "/vol0/local/plone/buildout-cache/eggs/plone.folder-3.0.1-py2.7.egg/plone/folder/ordered.py", line 230, in __getitem__
    value = self._getOb(key, None)
  File "/vol0/local/plone/buildout-cache/eggs/plone.folder-3.0.1-py2.7.egg/plone/folder/ordered.py", line 71, in _getOb
    return super(OrderedBTreeFolderBase, self)._getOb(id, default)
  File "/vol0/local/plone/buildout-cache/eggs/Products.BTreeFolder2-4.2-py2.7.egg/Products/BTreeFolder2/BTreeFolder2.py", line 220, in _getOb
    return self._tree[id].__of__(self)
AttributeError: 'FormFolder' object has no attribute '__of__'
End of upgrade path, main migration has finished.
The upgrade path did NOT reach current version.
Migration has failed

The "AttributeError: 'FormFolder' object has no attribute 'of'" error at the end leads me to believe there is some remnant of Plone.FormGen remaining that's blocking the upgrade, but I have no idea how to fix that. Any ideas?

Some more information:
This appears to be a long-standing (messages about it go back to 2013) bug related to a typo in PloneFormGen that results in it not getting cleanly uninstalled. If I try to go to portal_setup in the ZMI and run the ATContentTypes uninstall profile, I receive the following error:

pleonformgen
   ERROR: Step pleonformgen has an invalid import handler
   ERROR: Step pleonformgen has an invalid import handler
   ERROR: Step pleonformgen has an invalid import handler
   ERROR: Step pleonformgen has an invalid import handler

Note the typo of "ploneformgen" as "pleonformgen".

Googling for "pleonformgen" returns lots of hits for this situation, but sadly not one that I could find actually has a solution.

Is there a way to remove these remnants so I can upgrade the site?

Maybe someone can speakup on this but there's a package to help with this from the folks over at WildCard. Its called wildcard.fixmissing. That sounds to me what you want. I'd reccomend though for an update session to not do the zeo route and just have a single instance. less moving parts IMHO and less to load while upgrading.

bests!

Thanks for the response!

I tried wildcard.fixpersistentutilities, both without and with the FPU_GENERATE_MISSING_CLASSES true environment variable, with no success. This wildcard.fixmissing utility looks interesting, though. Does it produce any output?

I added wildcard.fixmissing to my eggs and then changed this section, which I think is what it's referring to when it talks about the instance:

############################################
# Major Parts
# ----------------------
# These common parts make use of sane base settings from
# base.cfg. To customize a part, just add whatever options
# you need. Read base.cfg for common settings.

[zeoserver]
<= zeoserver_base
recipe = plone.recipe.zeoserver
zeo-address = 127.0.0.1:8100
environment-vars =
    MISSING_pleonformgen Products.PloneFormGen

I have no idea if I did it right or not, though. :slight_smile: It installed the module during buildout but otherwise didn't produce any kind of special output.

Starting the site and trying to import the ATContentTypes uninstall profile still produced the errors referencing "pleonformgen" afterward, though.

You don't IMHO have a persistent utility problem but rather objects don't exist problem.

I would try to also uninstall any unneeded/unsupported add-ons before migrating. besides FormGen are their other add-ons that are gonna bork your upgrade? also read the documentation on upgrading ZODB to Py3. Look around the forums here.

I would try this:

  1. duplicate a clean instance of your production. Use a VM or whatever you're comfortable with. this means a Data.fs that's got none of the other things you've tried in it.
  2. create a non-zeo buildout for your migration. I often just use the develop.cfg as a starting point and add += i prefer this method because there's just less moving parts involved. you're the only person working with your site, so there's no need to worry about clients and connections etc.
  3. add to your buildout wildcard.fixmissing
  4. in your new buildout add environment-vars += MISSING_pleonformgen Products.PloneFormGen
  5. re-run buildout
  6. cross fingers? run your instance in FG mode to see what's barfing up. sometimes you have to get a little creative.

That seems like a solid list, and so many thanks for your response! We hadn't actually built out a lot of content (mostly it's been working on theme building so far), so what I wound up doing yesterday was just kind of giving up on upgrading and hand-migrating the content to the 5.2.1 dev server. I'm already about 3/4 of the way done that, so I think I'm going to just continue with that process and then try to do a .zexp export/import from the ZMI to re-duplicate the content on a new production install.

It will also give me a chance to practice migrating content that way, since that's a requirement for how they plan to manage the site in the future. (Building out content on a totally separate staging server and then having me migrate it to production in sections when it's approved.)

(The only not-supported-in-5.2.1 add-on I had was the previous PloneFormGen. Fortunately for me, very few add-ons -- collective.easyform now (to replace PloneFormGen), plone.app.mosaic, and pas.plugins.ldap.)

Please don't - use zipbackup / ziprestore from https://pypi.org/project/collective.recipe.backup/

Okay, I can certainly do that, but care to elaborate on why? (I was going by the instructions here: https://docs.plone.org/develop/plone/content/importexport.html )

(That's a full backup and restore tool, isn't it? While that's likely what I'm doing in this case, I also wanted to test this process out for later, where we'll be migrating only some content between the servers fairly regularly.)

Also, if I were to go the full-backup / full-restore route for this particular move, what advantage does that method have over the built-in bin/backup and bin/restore scripts?

Yes, on that page there is a callout box:

This method is applicable under very limited circumstances. Also note that for large Plone sites, the .zexp files generated is quite large, which could lead to memory errors. It is recommended to use this method only after trying other, more general methods.

Those scripts are also provided by collective.recipe.backup - it's all in the documentation I provided above.

Ahh, I see. I'd missed that.

The site isn't yet large -- I assumed that the "limited circumstances" had to do with the source and target sites needing to be on identical-everything, which will be the case. For the "migrate all the data back", it certainly makes sense to do it the way you propose, though.

Looking toward the future, what the stakeholders want is for content developers to post (and go through an approval cycle) on a development server and then when pages or sections of the site are approved, we move it over to the production server. While I've explained that we can achieve the overall goals (approval before publication, approval of updates, etc.) with the built-in workflow and in-place-staging support, they strongly want content development to happen on a completely separate server anyway. Is there a preferred method other than the .zexp export/import for moving just specific pages/objects/sections (presumably folders and their contents) rather than entire sites between servers?

Rather than manually "uploading" (1990's flashback) the zexp files (one for each of the folders?), I would try to convince the stakeholders to either use a ZEO cluster where your public server (ZEO client) is read only (and only published content is visible), or to use plone.restapi.

Workflow was designed to do exactly what your stakeholders want, I have found it immensely flexible and easy to set up even for complex scenarios with different sorts of states and triggers.

There may be alternate ideas to suit your use case (GatsbyJS?). Consider starting a new topic so others may chime in as well...

This is just a thought, maybe someone that knows more (than me) can comment.

In /portal_setup there you can see these import handlers.
Would it be possible to run the upgrade steps 
(that you see in the 'upgrades' tab, for everything except formgen  ?

After / Or it might be possible to remove that (misspelled) upgrade handler ?

Well, now, that's interesting: If I go to /portal_setup, I see no reference to it anywhere until I get to the Manage tab. But there, I see:

Steps with invalid step handlers

PloneFormGen
Import PloneFormGen settings 
Products.PloneFormGen.setuphandlers.importVarious

With a checkbox, and there's a button labelled "Delete selected steps". I'll try this and re-run the upgrade, then report back.

IT WORKED!!!

@espenmn , you have saved my bacon for about the 40th time. Thank you.

Now I just need to embark on the Python2->Python3 adventure. :slight_smile: Wish me luck!

1 Like

Sadly, I spoke too soon. The upgrade of the database went okay, and the site came up and displayed. However, a lot of things are behaving very strangely. The two biggest are that I can't seem to successfully traverse the navigation structure in a lot of widgets -- as an example, I wanted to redirect what folder an Events portlet was displaying events from, but it couldn't find any content outside of the language root folder and its direct descendants -- sub-folders didn't work, and traversing up to the root also didn't work (it would just claim they were empty).

Also, attempting to edit any image returns the following Traceback:

Traceback (innermost last):
  Module ZPublisher.WSGIPublisher, line 162, in transaction_pubevents
  Module transaction._manager, line 252, in commit
  Module transaction._manager, line 131, in commit
  Module transaction._transaction, line 311, in commit
  Module transaction._transaction, line 302, in commit
  Module transaction._transaction, line 447, in _commitResources
  Module transaction._transaction, line 421, in _commitResources
  Module ZODB.Connection, line 497, in commit
  Module ZODB.Connection, line 546, in _commit
  Module ZODB.Connection, line 595, in _store_objects
  Module ZODB.mvccadapter, line 170, in storeBlob
  Module ZEO.ClientStorage, line 586, in storeBlob
  Module ZODB.blob, line 435, in getPathForOID
AssertionError

Attempting to update the portal_catalogue results in the same error.

Okay, in the end I finished hand-porting all the content and just installed a totally fresh copy of Plone 5.2.1 to the production site, then pulled the database over from the dev site with plonebackup.zip/ziprestore. It's working fine now. I really, really, really appreciate everyone's help with this, nonetheless. :slight_smile:

Plone Foundation Code of Conduct