Example #1
0
 def test_initiate_propagate_rsrc_retriggers_check_rsrc_on_new_stack_update(
     self, mock_stack_load, mock_rcr, mock_cru, mock_crc, mock_pcr, mock_csc, mock_cid
 ):
     key = sync_point.make_key(self.resource.id, self.stack.current_traversal, self.is_update)
     mock_pcr.side_effect = sync_point.SyncPointNotFound(key)
     updated_stack = stack.Stack(
         self.ctx, self.stack.name, self.stack.t, self.stack.id, current_traversal="some_newy_trvl_uuid"
     )
     mock_stack_load.return_value = updated_stack
     self.worker._initiate_propagate_resource(
         self.ctx, self.resource.id, self.stack.current_traversal, self.is_update, self.resource, self.stack
     )
     mock_rcr.assert_called_once_with(self.ctx, self.is_update, self.resource.id, updated_stack)
Example #2
0
    def _retrigger_check_resource(self, cnxt, is_update, resource_id, stack):
        current_traversal = stack.current_traversal
        graph = self._compute_dependencies(stack).graph()
        key = sync_point.make_key(resource_id, current_traversal, is_update)
        predecessors = graph[key]

        def do_check(target_key, data):
            self.check_resource(resource_id, current_traversal,
                                data)

        try:
            sync_point.sync(cnxt, resource_id, current_traversal, is_update,
                            do_check, predecessors, {key: None})
        except sync_point.sync_points.NotFound:
            pass
Example #3
0
 def test_initiate_propagate_rsrc_retriggers_check_rsrc_on_new_stack_update(
         self, mock_stack_load, mock_rcr, mock_cru, mock_crc, mock_pcr,
         mock_csc, mock_cid):
     key = sync_point.make_key(self.resource.id,
                               self.stack.current_traversal,
                               self.is_update)
     mock_pcr.side_effect = sync_point.SyncPointNotFound(key)
     updated_stack = stack.Stack(self.ctx, self.stack.name, self.stack.t,
                                 self.stack.id,
                                 current_traversal='some_newy_trvl_uuid')
     mock_stack_load.return_value = updated_stack
     self.worker._initiate_propagate_resource(self.ctx, self.resource.id,
                                              self.stack.current_traversal,
                                              self.is_update, self.resource,
                                              self.stack)
     mock_rcr.assert_called_once_with(self.ctx, self.is_update,
                                      self.resource.id, updated_stack)
Example #4
0
File: worker.py Project: rh-s/heat
    def check_resource(self, cnxt, resource_id, current_traversal, data,
                       is_update):
        '''
        Process a node in the dependency graph.

        The node may be associated with either an update or a cleanup of its
        associated resource.
        '''
        adopt_data = data.get('adopt_stack_data')
        data = dict(sync_point.deserialize_input_data(data))
        try:
            cache_data = {in_data.get(
                'name'): in_data for in_data in data.values()
                if in_data is not None}
            cache_data['adopt_stack_data'] = adopt_data
            rsrc, stack = resource.Resource.load(cnxt, resource_id, is_update,
                                                 cache_data)
        except (exception.ResourceNotFound, exception.NotFound):
            return
        tmpl = stack.t

        if current_traversal != rsrc.stack.current_traversal:
            LOG.debug('[%s] Traversal cancelled; stopping.', current_traversal)
            return

        current_deps = ([tuple(i), (tuple(j) if j is not None else None)]
                        for i, j in rsrc.stack.current_deps['edges'])
        deps = dependencies.Dependencies(edges=current_deps)
        graph = deps.graph()

        if is_update:
            if (rsrc.replaced_by is not None and
                    rsrc.current_template_id != tmpl.id):
                return
            try:
                check_resource_update(rsrc, tmpl.id, data, self.engine_id)
            except resource.UpdateReplace:
                new_res_id = rsrc.make_replacement(tmpl.id)
                LOG.info("Replacing resource with new id %s", new_res_id)
                data = sync_point.serialize_input_data(data)
                self._rpc_client.check_resource(cnxt,
                                                new_res_id,
                                                current_traversal,
                                                data, is_update)
                return
            except resource.UpdateInProgress:
                if self._try_steal_engine_lock(cnxt, resource_id):
                    self._rpc_client.check_resource(cnxt,
                                                    resource_id,
                                                    current_traversal,
                                                    data, is_update)
                return
            except exception.ResourceFailure as ex:
                reason = 'Resource %s failed: %s' % (stack.action,
                                                     six.text_type(ex))
                self._handle_resource_failure(
                    cnxt, stack.id, current_traversal, reason)
                return

            input_data = construct_input_data(rsrc)
        else:
            try:
                check_resource_cleanup(rsrc, tmpl.id, data, self.engine_id)
            except resource.UpdateInProgress:
                if self._try_steal_engine_lock(cnxt, resource_id):
                    self._rpc_client.check_resource(cnxt,
                                                    resource_id,
                                                    current_traversal,
                                                    data, is_update)
                return
            except exception.ResourceFailure as ex:
                reason = 'Resource %s failed: %s' % (stack.action,
                                                     six.text_type(ex))
                self._handle_resource_failure(
                    cnxt, stack.id, current_traversal, reason)
                return

        graph_key = (resource_id, is_update)
        if graph_key not in graph and rsrc.replaces is not None:
            # If we are a replacement, impersonate the replaced resource for
            # the purposes of calculating whether subsequent resources are
            # ready, since everybody has to work from the same version of the
            # graph. Our real resource ID is sent in the input_data, so the
            # dependencies will get updated to point to this resource in time
            # for the next traversal.
            graph_key = (rsrc.replaces, is_update)

        try:
            for req, fwd in deps.required_by(graph_key):
                propagate_check_resource(
                    cnxt, self._rpc_client, req, current_traversal,
                    set(graph[(req, fwd)]), graph_key,
                    input_data if fwd else None, fwd)

            check_stack_complete(cnxt, rsrc.stack, current_traversal,
                                 resource_id, deps, is_update)
        except sync_point.SyncPointNotFound:
            # Reload the stack to determine the current traversal, and check
            # the SyncPoint for the current node to determine if it is ready.
            # If it is, then retrigger the current node with the appropriate
            # data for the latest traversal.
            stack = parser.Stack.load(cnxt, stack_id=rsrc.stack.id)
            if current_traversal == rsrc.stack.current_traversal:
                LOG.debug('[%s] Traversal sync point missing.',
                          current_traversal)
                return

            current_traversal = stack.current_traversal
            current_deps = ([tuple(i), (tuple(j) if j is not None else None)]
                            for i, j in stack.current_deps['edges'])
            deps = dependencies.Dependencies(edges=current_deps)
            key = sync_point.make_key(resource_id, current_traversal,
                                      is_update)
            predecessors = deps.graph()[key]

            def do_check(target_key, data):
                self.check_resource(resource_id, current_traversal,
                                    data)

            try:
                sync_point.sync(cnxt, resource_id, current_traversal,
                                is_update, do_check, predecessors, {key: None})
            except sync_point.sync_points.NotFound:
                pass