From 57a71eb07d393e5f7936b97745cefc6a6520aea9 Mon Sep 17 00:00:00 2001 From: Zane Bitter Date: Wed, 11 Jul 2012 11:02:13 -0400 Subject: [PATCH] Access Resource metadata through the new attribute Get rid of all the other code that was accessing this directly from the database and use only the Metadata descriptor. Change-Id: I36a7a00878d0b65f58ba282ebad78f77b37c4d07 Signed-off-by: Zane Bitter --- heat/engine/instance.py | 3 +- heat/engine/manager.py | 24 ++++++---- heat/engine/resources.py | 6 +-- heat/engine/wait_condition.py | 84 +++++++++++++++-------------------- 4 files changed, 57 insertions(+), 60 deletions(-) diff --git a/heat/engine/instance.py b/heat/engine/instance.py index a8f147dc..c48aa643 100644 --- a/heat/engine/instance.py +++ b/heat/engine/instance.py @@ -183,8 +183,7 @@ class Instance(resources.Resource): (userdata, 'startup', 'x-shellscript')] if 'Metadata' in self.t: - metadata = self.parsed_template('Metadata') - attachments.append((json.dumps(metadata), + attachments.append((json.dumps(self.metadata), 'cfn-init-data', 'x-cfninitdata')) metadata_server = resources.Metadata.server() diff --git a/heat/engine/manager.py b/heat/engine/manager.py index 366f80c2..247ccb1e 100644 --- a/heat/engine/manager.py +++ b/heat/engine/manager.py @@ -340,25 +340,33 @@ class EngineManager(manager.Manager): if not s: return ['stack', None] - r = db_api.resource_get_by_name_and_stack(None, resource_name, s.id) - if r is None: + stack = parser.Stack.load(None, s.id) + if resource_name not in stack: return ['resource', None] - return [None, r.rsrc_metadata] + resource = stack[resource_name] + + return [None, resource.metadata] def metadata_update(self, context, stack_id, resource_name, metadata): """ Update the metadata for the given resource. """ - r = db_api.resource_get_by_name_and_stack(None, resource_name, - stack_id) - if r is None: + s = db_api.stack_get(None, stack_id) + if s is None: + logger.warn("Stack %s not found" % stack_id) + return ['stack', None] + + stack = parser.Stack.load(None, s.id) + if resource_name not in stack: logger.warn("Resource not found %s:%s." % (stack_id, resource_name)) return ['resource', None] - r.update_and_save({'rsrc_metadata': metadata}) - return [None, metadata] + resource = stack[resource_name] + resource.metadata = metadata + + return [None, resource.metadata] @manager.periodic_task def _periodic_watcher_task(self, context): diff --git a/heat/engine/resources.py b/heat/engine/resources.py index 99c7e85c..40b88222 100644 --- a/heat/engine/resources.py +++ b/heat/engine/resources.py @@ -254,14 +254,14 @@ class Resource(object): except Exception as ex: logger.warn('db error %s' % str(ex)) - def _create_db(self, metadata=None): + def _store(self): '''Create the resource in the database''' try: rs = {'state': self.state, 'stack_id': self.stack.id, 'nova_instance': self.instance_id, 'name': self.name, - 'rsrc_metadata': metadata, + 'rsrc_metadata': self.metadata, 'stack_name': self.stack.name} new_rs = db_api.resource_create(self.context, rs) @@ -307,7 +307,7 @@ class Resource(object): logger.error('DB error %s' % str(ex)) elif new_state in (self.CREATE_COMPLETE, self.CREATE_FAILED): - self._create_db(metadata=self.parsed_template('Metadata')) + self._store() if new_state != old_state: self._add_event(new_state, reason) diff --git a/heat/engine/wait_condition.py b/heat/engine/wait_condition.py index 46c20499..a391925a 100644 --- a/heat/engine/wait_condition.py +++ b/heat/engine/wait_condition.py @@ -18,7 +18,6 @@ import logging import json from heat.common import exception -from heat.db import api as db_api from heat.engine import resources logger = logging.getLogger('heat.engine.wait_condition') @@ -44,6 +43,17 @@ class WaitConditionHandle(resources.Resource): self.name) +WAIT_STATUSES = ( + WAITING, + TIMEDOUT, + SUCCESS, +) = ( + 'WAITING', + 'TIMEDOUT', + 'SUCCESS', +) + + class WaitCondition(resources.Resource): properties_schema = {'Handle': {'Type': 'String', 'Required': True}, @@ -68,65 +78,45 @@ class WaitCondition(resources.Resource): return self.resource_id def handle_create(self): - self._get_handle_resource_id() - res_name = self.resource_id - - # keep polling our Metadata to see if the cfn-signal has written - # it yet. The execution here is limited by timeout. - tmo = eventlet.Timeout(self.timeout) - status = 'WAITING' - reason = '' - res = None - sleep_time = 1 + tmo = None try: - while status == 'WAITING': - try: - res = db_api.resource_get_by_name_and_stack(self.context, - res_name, - self.stack.id) - except Exception as ex: - logger.exception('resource %s not found' % res_name) - if 'not found' in ex: - # it has been deleted - status = 'DELETED' - else: - pass - - if res: - if res.rsrc_metadata: - meta = res.rsrc_metadata - status = meta.get('Status', - 'WAITING') - reason = meta.get('Reason', - 'Reason not provided') - logger.debug('got %s' % json.dumps(res.rsrc_metadata)) - if status == 'WAITING': - logger.debug('Waiting some more for the Metadata[Status]') - eventlet.sleep(sleep_time) - sleep_time = min(sleep_time * 2, self.timeout / 4) - if res: - res.expire() - - except eventlet.Timeout, t: + # keep polling our Metadata to see if the cfn-signal has written + # it yet. The execution here is limited by timeout. + with eventlet.Timeout(self.timeout) as tmo: + handle = self.stack[self._get_handle_resource_id()] + + status = WAITING + reason = '' + sleep_time = 1 + + while status == WAITING: + meta = handle.metadata + status = meta.get('Status', WAITING) + reason = meta.get('Reason', 'Reason not provided') + logger.debug('got %s' % json.dumps(meta)) + if status == WAITING: + logger.debug('Waiting for the Metadata[Status]') + eventlet.sleep(sleep_time) + sleep_time = min(sleep_time * 2, self.timeout / 4) + + except eventlet.Timeout as t: if t is not tmo: # not my timeout raise else: - status = 'TIMEDOUT' + status = TIMEDOUT reason = 'Timed out waiting for instance' - finally: - tmo.cancel() - if status != 'SUCCESS': + if status != SUCCESS: raise exception.Error(reason) def FnGetAtt(self, key): res = None if key == 'Data': try: - r = db_api.resource_get(self.context, self.id) - if r.rsrc_metadata and 'Data' in r.rsrc_metadata: - res = r.rsrc_metadata['Data'] + meta = self.metadata + if meta and 'Data' in meta: + res = meta['Data'] except Exception as ex: pass -- 2.45.2