'Store the stack in the database and return its ID.
If self.id is set, we update the existing stack.'

@profiler.trace('Stack.store', hide_args=False)
def store(self, backup=False, exp_trvsl=None, ignore_traversal_check=False):

    s = self.get_kwargs_for_cloning(keep_status=True, only_db=True)
    s['name'] = self.name
    s['backup'] = backup
    s['updated_at'] = self.updated_time
    if (self.t.id is None):
        stack_object.Stack.encrypt_hidden_parameters(self.t)
        s['raw_template_id'] = self.t.store(self.context)
    else:
        s['raw_template_id'] = self.t.id
    if (self.id is not None):
        if ((exp_trvsl is None) and (not ignore_traversal_check)):
            exp_trvsl = self.current_traversal
        if self.convergence:
            updated = stack_object.Stack.select_and_update(self.context, self.id, s, exp_trvsl=exp_trvsl)
            if (not updated):
                return None
        else:
            stack_object.Stack.update_by_id(self.context, self.id, s)
    else:
        if (not self.user_creds_id):
            if (cfg.CONF.deferred_auth_method == 'trusts'):
                keystone = self.clients.client('keystone')
                trust_ctx = keystone.create_trust_context()
                new_creds = ucreds_object.UserCreds.create(trust_ctx)
            else:
                new_creds = ucreds_object.UserCreds.create(self.context)
            s['user_creds_id'] = new_creds.id
            self.user_creds_id = new_creds.id
        if self.convergence:
            self.current_traversal = uuidutils.generate_uuid()
            s['current_traversal'] = self.current_traversal
        new_s = stack_object.Stack.create(self.context, s)
        self.id = new_s.id
        self.created_time = new_s.created_at
    if self.tags:
        stack_tag_object.StackTagList.set(self.context, self.id, self.tags)
    self._set_param_stackid()
    return self.id
