← Back to team overview

cloud-init-dev team mailing list archive

[Merge] lp:~harlowja/cloud-init/cloud-handler-finalizers into lp:cloud-init

 

Joshua Harlow has proposed merging lp:~harlowja/cloud-init/cloud-handler-finalizers into lp:cloud-init.

Requested reviews:
  cloud init development team (cloud-init-dev)
Related bugs:
  Bug #1203368 in cloud-init: "Always finalize handlers"
  https://bugs.launchpad.net/cloud-init/+bug/1203368

For more details, see:
https://code.launchpad.net/~harlowja/cloud-init/cloud-handler-finalizers/+merge/176024
-- 
https://code.launchpad.net/~harlowja/cloud-init/cloud-handler-finalizers/+merge/176024
Your team cloud init development team is requested to review the proposed merge of lp:~harlowja/cloud-init/cloud-handler-finalizers into lp:cloud-init.
=== modified file 'cloudinit/stages.py'
--- cloudinit/stages.py	2013-06-19 06:44:00 +0000
+++ cloudinit/stages.py	2013-07-20 19:47:24 +0000
@@ -383,36 +383,62 @@
         # Form our cloud interface
         data = self.cloudify()
 
-        # Init the handlers first
-        called = []
-        for (_ctype, mod) in c_handlers.iteritems():
-            if mod in called:
-                continue
-            handlers.call_begin(mod, data, frequency)
-            called.append(mod)
-
-        # Walk the user data
-        part_data = {
-            'handlers': c_handlers,
-            # Any new handlers that are encountered get writen here
-            'handlerdir': idir,
-            'data': data,
-            # The default frequency if handlers don't have one
-            'frequency': frequency,
-            # This will be used when new handlers are found
-            # to help write there contents to files with numbered
-            # names...
-            'handlercount': 0,
-        }
-        handlers.walk(user_data_msg, handlers.walker_callback, data=part_data)
-
-        # Give callbacks opportunity to finalize
-        called = []
-        for (_ctype, mod) in c_handlers.iteritems():
-            if mod in called:
-                continue
-            handlers.call_end(mod, data, frequency)
-            called.append(mod)
+        # This list contains the modules initialized (so that we only finalize
+        # ones that were actually initialized)
+        inited_handlers = []
+
+        def init_handlers():
+            # Init the handlers first
+            called = []
+            for (_ctype, mod) in c_handlers.iteritems():
+                if mod in called:
+                    # Avoid initing the same module twice (if said module
+                    # is registered to more than one content-type).
+                    continue
+                handlers.call_begin(mod, data, frequency)
+                inited_handlers.append(mod)
+                called.append(mod)
+
+        def walk_handlers():
+            # Walk the user data
+            part_data = {
+                'handlers': c_handlers,
+                # Any new handlers that are encountered get writen here
+                'handlerdir': idir,
+                'data': data,
+                # The default frequency if handlers don't have one
+                'frequency': frequency,
+                # This will be used when new handlers are found
+                # to help write there contents to files with numbered
+                # names...
+                'handlercount': 0,
+            }
+            handlers.walk(user_data_msg, handlers.walker_callback,
+                          data=part_data)
+
+        def finalize_handlers():
+            # Give callbacks opportunity to finalize
+            called = []
+            for (_ctype, mod) in c_handlers.iteritems():
+                if mod in called:
+                    # Avoid finalizing the same module twice (if said module
+                    # is registered to more than one content-type).
+                    continue
+                if mod not in inited_handlers:
+                    # Said module was never inited in the first place, so lets
+                    # not attempt to finalize those that never got called.
+                    continue
+                called.append(mod)
+                try:
+                    handlers.call_end(mod, data, frequency)
+                except:
+                    util.logexc(LOG, "Failed to finalize handler: %s", mod)
+
+        try:
+            init_handlers()
+            walk_handlers()
+        finally:
+            finalize_handlers()
 
         # Perform post-consumption adjustments so that
         # modules that run during the init stage reflect


Follow ups