Files
cloudbase-init/cloudbaseinit/plugins/windows/userdata.py
2014-01-20 01:05:10 +02:00

120 lines
4.7 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 Cloudbase Solutions Srl
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import email
from cloudbaseinit.metadata.services import base as metadata_services_base
from cloudbaseinit.openstack.common import log as logging
from cloudbaseinit.plugins import base
from cloudbaseinit.plugins.windows import userdatautils
from cloudbaseinit.plugins.windows.userdataplugins import factory
LOG = logging.getLogger(__name__)
class UserDataPlugin(base.BasePlugin):
_part_handler_content_type = "text/part-handler"
def execute(self, service, shared_data):
try:
user_data = service.get_user_data('openstack')
except metadata_services_base.NotExistingMetadataException:
return (base.PLUGIN_EXECUTION_DONE, False)
if not user_data:
return (base.PLUGIN_EXECUTION_DONE, False)
return self._process_user_data(user_data)
def _parse_mime(self, user_data):
return email.message_from_string(user_data).walk()
def _process_user_data(self, user_data):
plugin_status = base.PLUGIN_EXECUTION_DONE
reboot = False
LOG.debug('User data content:\n%s' % user_data)
if user_data.startswith('Content-Type: multipart'):
user_data_plugins_factory = factory.UserDataPluginsFactory()
user_data_plugins = user_data_plugins_factory.load_plugins()
user_handlers = {}
for part in self._parse_mime(user_data):
(plugin_status, reboot) = self._process_part(part,
user_data_plugins,
user_handlers)
if reboot:
break
return (plugin_status, reboot)
else:
return self._process_non_multi_part(user_data)
def _process_part(self, part, user_data_plugins, user_handlers):
ret_val = None
content_type = part.get_content_type()
user_data_plugin = user_data_plugins.get(content_type)
if not user_data_plugin:
LOG.info("Userdata plugin not found for content type: %s" %
content_type)
else:
try:
if content_type == self._part_handler_content_type:
user_handlers.update(user_data_plugin.process(part))
else:
handler_func = user_handlers.get(part.get_content_type())
self._begin_part_process_event(part, handler_func)
LOG.info("Executing user data plugin: %s" %
user_data_plugin.__class__.__name__)
ret_val = user_data_plugin.process(part)
self._end_part_process_event(part, handler_func)
except Exception, ex:
LOG.error('Exception during multipart part handling: '
'%(content_type)s, %(filename)s' %
{'content_type': part.get_content_type(),
'filename': part.get_filename()})
LOG.exception(ex)
return self._get_plugin_return_value(ret_val)
def _begin_part_process_event(self, part, handler_func):
if handler_func:
handler_func("", "__begin__", part.get_filename(),
part.get_payload())
def _end_part_process_event(self, part, handler_func):
if handler_func:
handler_func("", "__end__", part.get_filename(),
part.get_payload())
def _get_plugin_return_value(self, ret_val):
plugin_status = base.PLUGIN_EXECUTION_DONE
reboot = False
if ret_val >= 1001 and ret_val <= 1003:
reboot = bool(ret_val & 1)
if ret_val & 2:
plugin_status = base.PLUGIN_EXECUTE_ON_NEXT_BOOT
return (plugin_status, reboot)
def _process_non_multi_part(self, user_data):
ret_val = userdatautils.execute_user_data_script(user_data)
return self._get_plugin_return_value(ret_val)