'Update the stack template and trigger convergence for resources.'

@profiler.trace('Stack.converge_stack', hide_args=False)
def converge_stack(self, template, action=UPDATE, new_stack=None):

    if (action not in [self.CREATE, self.ADOPT]):
        self.prev_raw_template_id = getattr(self.t, 'id', None)
    self.defn = self.defn.clone_with_new_template(template, self.identifier(), clear_resource_data=True)
    self.reset_dependencies()
    self._resources = None
    if (action is not self.CREATE):
        self.updated_time = oslo_timeutils.utcnow()
    if (new_stack is not None):
        self.disable_rollback = new_stack.disable_rollback
        self.timeout_mins = new_stack.timeout_mins
        self.defn = new_stack.defn
        self._set_param_stackid()
        self.tags = new_stack.tags
        if new_stack.tags:
            stack_tag_object.StackTagList.set(self.context, self.id, new_stack.tags)
        else:
            stack_tag_object.StackTagList.delete(self.context, self.id)
    self.action = action
    self.status = self.IN_PROGRESS
    self.status_reason = ('Stack    %s    started' % self.action)
    previous_traversal = self.current_traversal
    self.current_traversal = uuidutils.generate_uuid()
    stack_id = self.store(exp_trvsl=previous_traversal)
    if (stack_id is None):
        LOG.warning('Failed    to    store    stack    %(name)s    with    traversal    ID    %(trvsl_id)s,    aborting    stack    %(action)s', {'name': self.name, 'trvsl_id': previous_traversal, 'action': self.action})
        return
    self._send_notification_and_add_event()
    if previous_traversal:
        sync_point.delete_all(self.context, self.id, previous_traversal)
    self.thread_group_mgr.start(self.id, self._converge_create_or_update)
