Example #1
0
    def delete_stack(self, cnxt, stack_identity):
        """
        The delete_stack method deletes a given stack.

        :param cnxt: RPC context.
        :param stack_identity: Name of the stack you want to delete.
        """
        def remote_stop(lock_engine_id):
            rpc = proxy.RpcProxy(lock_engine_id, "1.0")
            msg = rpc.make_msg("stop_stack", stack_identity=stack_identity)
            timeout = cfg.CONF.engine_life_check_timeout
            try:
                rpc.call(cnxt, msg, topic=lock_engine_id, timeout=timeout)
            except rpc_common.Timeout:
                return False

        st = self._get_stack(cnxt, stack_identity)
        logger.info(_('Deleting stack %s') % st.name)
        stack = parser.Stack.load(cnxt, stack=st)

        lock = stack_lock.StackLock(cnxt, stack, self.engine_id)
        acquire_result = lock.try_acquire()

        # Successfully acquired lock
        if acquire_result is None:
            self.thread_group_mgr.start_with_acquired_lock(stack, lock,
                                                           stack.delete)
            return

        # Current engine has the lock
        elif acquire_result == self.engine_id:
            self.thread_group_mgr.stop(stack.id)

        # Another active engine has the lock
        elif stack_lock.StackLock.engine_alive(cnxt, acquire_result):
            stop_result = remote_stop(acquire_result)
            if stop_result is None:
                logger.debug(_("Successfully stopped remote task on engine %s")
                             % acquire_result)
            else:
                raise exception.StopActionFailed(stack_name=stack.name,
                                                 engine_id=acquire_result)

        # If the lock isn't released here, then the call to
        # start_with_lock below will raise an ActionInProgress
        # exception.  Ideally, we wouldn't be calling another
        # release() here, since it should be called as soon as the
        # ThreadGroup is stopped.  But apparently there's a race
        # between release() the next call to lock.acquire().
        db_api.stack_lock_release(stack.id, acquire_result)

        # There may be additional resources that we don't know about
        # if an update was in-progress when the stack was stopped, so
        # reload the stack from the database.
        st = self._get_stack(cnxt, stack_identity)
        stack = parser.Stack.load(cnxt, stack=st)

        self.thread_group_mgr.start_with_lock(cnxt, stack, self.engine_id,
                                              stack.delete)
        return None
Example #2
0
    def delete_stack(self, cnxt, stack_identity):
        """
        The delete_stack method deletes a given stack.

        :param cnxt: RPC context.
        :param stack_identity: Name of the stack you want to delete.
        """
        def remote_stop(lock_engine_id):
            rpc = proxy.RpcProxy(lock_engine_id, "1.0")
            msg = rpc.make_msg("stop_stack", stack_identity=stack_identity)
            timeout = cfg.CONF.engine_life_check_timeout
            try:
                rpc.call(cnxt, msg, topic=lock_engine_id, timeout=timeout)
            except rpc_common.Timeout:
                return False

        st = self._get_stack(cnxt, stack_identity)
        logger.info(_('Deleting stack %s') % st.name)
        stack = parser.Stack.load(cnxt, stack=st)

        lock = stack_lock.StackLock(cnxt, stack, self.engine_id)
        acquire_result = lock.try_acquire()

        # Successfully acquired lock
        if acquire_result is None:
            self.thread_group_mgr.start_with_acquired_lock(stack, lock,
                                                           stack.delete)
            return

        # Current engine has the lock
        elif acquire_result == self.engine_id:
            self.thread_group_mgr.stop(stack.id)

        # Another active engine has the lock
        elif stack_lock.StackLock.engine_alive(cnxt, acquire_result):
            stop_result = remote_stop(acquire_result)
            if stop_result is None:
                logger.debug(_("Successfully stopped remote task on engine %s")
                             % acquire_result)
            else:
                raise exception.StopActionFailed(stack_name=stack.name,
                                                 engine_id=acquire_result)

        # If the lock isn't released here, then the call to
        # start_with_lock below will raise an ActionInProgress
        # exception.  Ideally, we wouldn't be calling another
        # release() here, since it should be called as soon as the
        # ThreadGroup is stopped.  But apparently there's a race
        # between release() the next call to lock.acquire().
        db_api.stack_lock_release(stack.id, acquire_result)

        # There may be additional resources that we don't know about
        # if an update was in-progress when the stack was stopped, so
        # reload the stack from the database.
        st = self._get_stack(cnxt, stack_identity)
        stack = parser.Stack.load(cnxt, stack=st)

        self.thread_group_mgr.start_with_lock(cnxt, stack, self.engine_id,
                                              stack.delete)
        return None
Example #3
0
 def release(self, stack_id):
     """Release a stack lock."""
     # Only the engine that owns the lock will be releasing it.
     result = db_api.stack_lock_release(stack_id, self.engine_id)
     if result is True:
         LOG.warning(_("Lock was already released on stack %s!") % stack_id)
     else:
         LOG.debug("Engine %(engine)s released lock on stack "
                   "%(stack)s" % {'engine': self.engine_id,
                                  'stack': stack_id})
Example #4
0
 def release(self, stack_id):
     """Release a stack lock."""
     # Only the engine that owns the lock will be releasing it.
     result = db_api.stack_lock_release(stack_id, self.engine_id)
     if result is True:
         LOG.warn(_LW("Lock was already released on stack %s!"), stack_id)
     else:
         LOG.debug("Engine %(engine)s released lock on stack "
                   "%(stack)s" % {'engine': self.engine_id,
                                  'stack': stack_id})
Example #5
0
 def release(self):
     """Release a stack lock."""
     # Only the engine that owns the lock will be releasing it.
     result = db_api.stack_lock_release(self.stack.id, self.engine_id)
     if result is True:
         logger.warning(
             _("Lock was already released on stack %s!") % self.stack.id)
     else:
         logger.debug(
             _("Engine %(engine)s released lock on stack "
               "%(stack)s") % {
                   'engine': self.engine_id,
                   'stack': self.stack.id
               })
Example #6
0
 def release(cls, stack_id, engine_id):
     return db_api.stack_lock_release(stack_id, engine_id)
Example #7
0
 def release(cls, stack_id, engine_id):
     return db_api.stack_lock_release(stack_id, engine_id)