Entfernen von Local Utilities, Subscribers, Adapters und Portal Tools

Häufig werden Local Persistent Utilities beim Deinstallieren eines Produkts nicht ebenfalls entfernt.

Bemerkung

Mit wildcard.fixpersistentutilities steht nun ein Modul zur Verfügung, mit dem sich Local Utilities, Subscribers, Adapters und Portal Tools auf der Web-Oberfläche entfernen lassen.

Symptome

Nach dem Deinstallieren solcher Produkte kann es z.B. folgende Fehlermeldungen geben:

AttributeError: type object 'IQueue' has no attribute '__iro__'

oder:

AttributeError: type object 'ISalt' has no attribute '__iro__'

Entfernen von Local Persistent Utilities

  1. Starten der Instanz im Debug-Modus:

    $ ./bin/instance debug
    
  2. Anschließend holen wir uns den site manager der Site Plone. àpp` referenziert dabei auf das Zope-Root-Objekt:

    sm = app.Plone.getSiteManager()
    
  3. Nun importieren wir das Interface des Utility. Anschließend melden wir es ab und löschen es schließlich. Dies sieht z.B. für Singing & Dancing so aus:

    from collective.singing.interfaces import ISalt
    from collective.singing.async import IQueue
    
    util_obj = sm.getUtility(ISalt)
    sm.unregisterUtility(provided=ISalt)
    del util_obj
    sm.utilities.unsubscribe((), ISalt)
    del sm.utilities.__dict__['_provided'][ISalt]
    del sm.utilities._subscribers[0][ISalt]
    
    util = sm.queryUtility(IQueue, name='collective.dancing.jobs')
    sm.unregisterUtility(util, IQueue, name='collective.dancing.jobs')
    del util
    del sm.utilities._subscribers[0][IQueue]
    

    Dabei unterscheidet sich das Vorgehen, da für ISalt ein unnamed utility und für IQueue ein named utility registriert sind.

  4. Anschließend müssen die Änderungen noch an der ZODB commited werden:

    import transaction
    transaction.commit()
    app._p_jar.sync()
    

Entfernen von Subscribers, Adapters und Providers

sm = app.Plone.getSiteManager()

adapters = sm.utilities._adapters
for x in adapters[0].keys():
    if x.__module__.find("my.package") != -1:
      print "deleting %s" % x
      del adapters[0][x]
sm.utilities._adapters = adapters

subscribers = sm.utilities._subscribers
for x in subscribers[0].keys():
    if x.__module__.find("my.package") != -1:
      print "deleting %s" % x
      del subscribers[0][x]
sm.utilities._subscribers = subscribers

provided = sm.utilities._provided
for x in provided.keys():
    if x.__module__.find("my.package") != -1:
      print "deleting %s" % x
      del provided[x]
sm.utilities._provided = provided

from transaction import commit
commit()
app._p_jar.sync()
Plone

Die ID der Site

my.package

Das Paket, aus dem Subscriber, Adapter und Provider kommen

Entfernen von Portal Tools

Nach dem Entfernen von lokalen persistenten Komponenten muss ggf. auch noch das Portal Setup Tool bereinigt werden:

setup_tool = app.Plone.portal_setup
toolset = setup_tool.getToolsetRegistry()
if 'my.package' in toolset._required.keys():
    del toolset._required['my.package']
    setup_tool._toolset_registry = toolset

from transaction import commit
commit()
app._p_jar.sync()