From 198065f2ca711f1ca2f709a03b47255d4c4b754e Mon Sep 17 00:00:00 2001 From: Alessandro Pilotti Date: Wed, 19 Feb 2014 00:34:50 +0200 Subject: [PATCH] Adds support for multiple instances Saves plugins data in a per-instance section. This is useful in case an instance is snapshotted and new instances are booted from the new image. --- cloudbaseinit/init.py | 26 +++++++++++++------ cloudbaseinit/metadata/services/base.py | 3 +++ .../metadata/services/baseopenstackservice.py | 3 +++ cloudbaseinit/osutils/windows.py | 2 +- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/cloudbaseinit/init.py b/cloudbaseinit/init.py index 420a8141..36d82b46 100644 --- a/cloudbaseinit/init.py +++ b/cloudbaseinit/init.py @@ -41,18 +41,24 @@ LOG = logging.getLogger(__name__) class InitManager(object): _PLUGINS_CONFIG_SECTION = 'Plugins' - def _get_plugin_status(self, osutils, plugin_name): + def _get_plugins_section(self, instance_id): + if not instance_id: + return self._PLUGINS_CONFIG_SECTION + else: + return instance_id + "/" + self._PLUGINS_CONFIG_SECTION + + def _get_plugin_status(self, osutils, instance_id, plugin_name): return osutils.get_config_value(plugin_name, - self._PLUGINS_CONFIG_SECTION) + self._get_plugins_section(instance_id)) - def _set_plugin_status(self, osutils, plugin_name, status): + def _set_plugin_status(self, osutils, instance_id, plugin_name, status): osutils.set_config_value(plugin_name, status, - self._PLUGINS_CONFIG_SECTION) + self._get_plugins_section(instance_id)) - def _exec_plugin(self, osutils, service, plugin, shared_data): + def _exec_plugin(self, osutils, service, plugin, instance_id, shared_data): plugin_name = plugin.get_name() - status = self._get_plugin_status(osutils, plugin_name) + status = self._get_plugin_status(osutils, instance_id, plugin_name) if status == plugins_base.PLUGIN_EXECUTION_DONE: LOG.debug('Plugin \'%(plugin_name)s\' execution already done, ' 'skipping' % locals()) @@ -62,7 +68,8 @@ class InitManager(object): try: (status, reboot_required) = plugin.execute(service, shared_data) - self._set_plugin_status(osutils, plugin_name, status) + self._set_plugin_status(osutils, instance_id, plugin_name, + status) return reboot_required except Exception, ex: LOG.error('plugin \'%(plugin_name)s\' failed ' @@ -98,6 +105,9 @@ class InitManager(object): LOG.info('Metadata service loaded: \'%s\'' % service.get_name()) + instance_id = service.get_instance_id() + LOG.debug('Instance id: %s', instance_id) + plugins = plugins_factory.PluginFactory().load_plugins() plugins_shared_data = {} @@ -107,7 +117,7 @@ class InitManager(object): for plugin in plugins: if self._check_plugin_os_requirements(osutils, plugin): if self._exec_plugin(osutils, service, plugin, - plugins_shared_data): + instance_id, plugins_shared_data): reboot_required = True if CONF.allow_reboot: break diff --git a/cloudbaseinit/metadata/services/base.py b/cloudbaseinit/metadata/services/base.py index 0c0ffa88..7d4b8424 100644 --- a/cloudbaseinit/metadata/services/base.py +++ b/cloudbaseinit/metadata/services/base.py @@ -78,6 +78,9 @@ class BaseMetadataService(object): self._cache[path] = data return data + def get_instance_id(self): + pass + def get_content(self, name): pass diff --git a/cloudbaseinit/metadata/services/baseopenstackservice.py b/cloudbaseinit/metadata/services/baseopenstackservice.py index 934d0ecc..5da7a47a 100644 --- a/cloudbaseinit/metadata/services/baseopenstackservice.py +++ b/cloudbaseinit/metadata/services/baseopenstackservice.py @@ -56,6 +56,9 @@ class BaseOpenStackService(base.BaseMetadataService): else: return data + def get_instance_id(self): + return self._get_meta_data().get('uuid') + def get_host_name(self): return self._get_meta_data().get('hostname') diff --git a/cloudbaseinit/osutils/windows.py b/cloudbaseinit/osutils/windows.py index 76703d71..db3aa1a4 100644 --- a/cloudbaseinit/osutils/windows.py +++ b/cloudbaseinit/osutils/windows.py @@ -389,7 +389,7 @@ class WindowsUtils(base.BaseOSUtils): def _get_config_key_name(self, section): key_name = self._config_key if section: - key_name += section + '\\' + key_name += section.replace('/', '\\') + '\\' return key_name def set_config_value(self, name, value, section=None):