예제 #1
0
def ActionProc(ctx, action_id):
    """Action process."""

    # Step 1: materialize the action object
    action = Action.load(ctx, action_id=action_id, project_safe=False)
    if action is None:
        LOG.error('Action "%s" could not be found.', action_id)
        return False

    EVENT.info(action, consts.PHASE_START, action_id[:8])

    reason = 'Action completed'
    success = True
    try:
        # Step 2: execute the action
        result, reason = action.execute()
        if result == action.RES_RETRY:
            success = False
    except Exception as ex:
        # We catch exception here to make sure the following logics are
        # executed.
        result = action.RES_ERROR
        reason = six.text_type(ex)
        LOG.exception('Unexpected exception occurred during action '
                      '%(action)s (%(id)s) execution: %(reason)s',
                      {'action': action.action, 'id': action.id,
                       'reason': reason})
        success = False
    finally:
        # NOTE: locks on action is eventually released here by status update
        action.set_status(result, reason)

    return success
예제 #2
0
파일: base.py 프로젝트: GingoBang/senlin
def ActionProc(context, action_id):
    '''Action process.'''

    # Step 1: materialize the action object
    action = Action.load(context, action_id=action_id)
    if action is None:
        LOG.error(_LE('Action "%s" could not be found.'), action_id)
        return False

    # TODO(Anyone): Remove context usage in event module
    EVENT.info(action.context, action, action.action, 'START')

    reason = 'Action completed'
    success = True
    try:
        # Step 2: execute the action
        result, reason = action.execute()
    except Exception as ex:
        # We catch exception here to make sure the following logics are
        # executed.
        result = action.RES_ERROR
        reason = six.text_type(ex)
        LOG.exception(_('Unexpected exception occurred during action '
                        '%(action)s (%(id)s) execution: %(reason)s'),
                      {'action': action.action, 'id': action.id,
                       'reason': reason})
        success = False
    finally:
        # NOTE: locks on action is eventually released here by status update
        action.set_status(result, reason)

    return success
예제 #3
0
    def set_status(self, result, reason=None):
        """Set action status based on return value from execute."""

        timestamp = wallclock()

        if result == self.RES_OK:
            status = self.SUCCEEDED
            ao.Action.mark_succeeded(self.context, self.id, timestamp)

        elif result == self.RES_ERROR:
            status = self.FAILED
            ao.Action.mark_failed(self.context, self.id, timestamp,
                                  reason or 'ERROR')

        elif result == self.RES_TIMEOUT:
            status = self.FAILED
            ao.Action.mark_failed(self.context, self.id, timestamp,
                                  reason or 'TIMEOUT')

        elif result == self.RES_CANCEL:
            status = self.CANCELLED
            ao.Action.mark_cancelled(self.context, self.id, timestamp)

        elif result == self.RES_LIFECYCLE_COMPLETE:
            status = self.SUCCEEDED
            ao.Action.mark_ready(self.context, self.id, timestamp)

        else:  # result == self.RES_RETRY:
            retries = self.data.get('retries', 0)
            # Action failed at the moment, but can be retried
            # retries time is configurable
            if retries < cfg.CONF.lock_retry_times:
                status = self.READY
                retries += 1

                self.data.update({'retries': retries})
                ao.Action.abandon(self.context, self.id, {'data': self.data})
                # sleep for a while
                eventlet.sleep(cfg.CONF.lock_retry_interval)
                dispatcher.start_action(self.id)
            else:
                status = self.RES_ERROR
                if not reason:
                    reason = ('Exceeded maximum number of retries (%d)'
                              '') % cfg.CONF.lock_retry_times
                ao.Action.mark_failed(self.context, self.id, timestamp, reason)

        if status == self.SUCCEEDED:
            EVENT.info(self, consts.PHASE_END, reason or 'SUCCEEDED')
        elif status == self.READY:
            EVENT.warning(self, consts.PHASE_ERROR, reason or 'RETRY')
        else:
            EVENT.error(self, consts.PHASE_ERROR, reason or 'ERROR')

        self.status = status
        self.status_reason = reason
예제 #4
0
파일: node.py 프로젝트: KongJustin/senlin
    def do_create(self, context):
        if self.status != self.INIT:
            LOG.error(_LE('Node is in status "%s"'), self.status)
            return False
        self.set_status(context, self.CREATING, reason='Creation in progress')
        event_mod.info(context, self, 'create')
        try:
            physical_id = profile_base.Profile.create_object(context, self)
        except exception.InternalError as ex:
            self._handle_exception(context, 'create', self.ERROR, ex)
            return False
        if not physical_id:
            return False

        status_reason = 'Creation succeeded'
        self.set_status(context, self.ACTIVE, status_reason)
        self.physical_id = physical_id
        self.store(context)
        return True
예제 #5
0
파일: node.py 프로젝트: KongJustin/senlin
    def do_create(self, context):
        if self.status != self.INIT:
            LOG.error(_LE('Node is in status "%s"'), self.status)
            return False
        self.set_status(context, self.CREATING, reason='Creation in progress')
        event_mod.info(context, self, 'create')
        try:
            physical_id = profile_base.Profile.create_object(context, self)
        except exception.InternalError as ex:
            self._handle_exception(context, 'create', self.ERROR, ex)
            return False
        if not physical_id:
            return False

        status_reason = 'Creation succeeded'
        self.set_status(context, self.ACTIVE, status_reason)
        self.physical_id = physical_id
        self.store(context)
        return True
예제 #6
0
    def test_info(self, mock_dump):
        entity = mock.Mock(id='1234567890')
        entity.name = 'fake_obj'
        action = mock.Mock(entity=entity, action='ACTION_NAME')

        res = event.info(action, 'P1', 'R1', 'TS1')

        self.assertIsNone(res)
        mock_dump.assert_called_once_with(logging.INFO, action, 'P1', 'R1',
                                          'TS1')
예제 #7
0
    def store(self, context):
        '''Store the cluster in database and return its ID.

        If the ID already exists, we do an update.
        '''

        values = {
            'name': self.name,
            'profile_id': self.profile_id,
            'user': self.user,
            'project': self.project,
            'domain': self.domain,
            'parent': self.parent,
            'init_time': self.init_time,
            'created_time': self.created_time,
            'updated_time': self.updated_time,
            'deleted_time': self.deleted_time,
            'min_size': self.min_size,
            'max_size': self.max_size,
            'desired_capacity': self.desired_capacity,
            'next_index': self.next_index,
            'timeout': self.timeout,
            'status': self.status,
            'status_reason': self.status_reason,
            'meta_data': self.metadata,
            'data': self.data,
        }

        timestamp = timeutils.utcnow()
        if self.id:
            values['updated_time'] = timestamp
            db_api.cluster_update(context, self.id, values)
            event_mod.info(context, self, 'update')
        else:
            self.init_time = timestamp
            values['init_time'] = timestamp
            cluster = db_api.cluster_create(context, values)
            self.id = cluster.id
            event_mod.info(context, self, 'create')

        self._load_runtime_data(context)
        return self.id
예제 #8
0
    def store(self, context):
        '''Store the cluster in database and return its ID.

        If the ID already exists, we do an update.
        '''

        values = {
            'name': self.name,
            'profile_id': self.profile_id,
            'user': self.user,
            'project': self.project,
            'domain': self.domain,
            'parent': self.parent,
            'init_time': self.init_time,
            'created_time': self.created_time,
            'updated_time': self.updated_time,
            'deleted_time': self.deleted_time,
            'min_size': self.min_size,
            'max_size': self.max_size,
            'desired_capacity': self.desired_capacity,
            'next_index': self.next_index,
            'timeout': self.timeout,
            'status': self.status,
            'status_reason': self.status_reason,
            'meta_data': self.metadata,
            'data': self.data,
        }

        timestamp = timeutils.utcnow()
        if self.id:
            values['updated_time'] = timestamp
            db_api.cluster_update(context, self.id, values)
            event_mod.info(context, self, 'update')
        else:
            self.init_time = timestamp
            values['init_time'] = timestamp
            cluster = db_api.cluster_create(context, values)
            self.id = cluster.id
            event_mod.info(context, self, 'create')

        self._load_runtime_data(context)
        return self.id
예제 #9
0
파일: node.py 프로젝트: KongJustin/senlin
    def do_delete(self, context):
        if not self.physical_id:
            db_api.node_delete(context, self.id)
            return True

        # TODO(Qiming): check if actions are working on it and can be canceled
        self.set_status(context, self.DELETING, reason='Deletion in progress')
        event_mod.info(context, self, 'delete')
        try:
            res = profile_base.Profile.delete_object(context, self)
        except exception.ResourceStatusError as ex:
            self._handle_exception(context, 'delete', self.ERROR, ex)
            res = False

        if res:
            db_api.node_delete(context, self.id)
            return True
        else:
            self.set_status(context, self.ERROR, reason='Deletion failed')
            return False
예제 #10
0
파일: node.py 프로젝트: tengqm/senlin
    def do_create(self, context):
        if self.status != self.INIT:
            LOG.error(_LE('Node is in status "%s"'), self.status)
            return False
        self.set_status(context, self.CREATING, reason='Creation in progress')
        event_mod.info(context, self, 'create')
        physical_id = profile_base.Profile.create_object(context, self)
        if not physical_id:
            return False

        if self.cluster_id is not None:
            self.index = db_api.cluster_get_next_index(context,
                                                       self.cluster_id)

        self.physical_id = physical_id
        self.created_time = datetime.datetime.utcnow()
        self.status = self.ACTIVE
        self.status_reason = 'Creation succeeded'
        self.store(context)
        return True
예제 #11
0
파일: node.py 프로젝트: KongJustin/senlin
    def do_delete(self, context):
        if not self.physical_id:
            db_api.node_delete(context, self.id)
            return True

        # TODO(Qiming): check if actions are working on it and can be canceled
        self.set_status(context, self.DELETING, reason='Deletion in progress')
        event_mod.info(context, self, 'delete')
        try:
            res = profile_base.Profile.delete_object(context, self)
        except exception.ResourceStatusError as ex:
            self._handle_exception(context, 'delete', self.ERROR, ex)
            res = False

        if res:
            db_api.node_delete(context, self.id)
            return True
        else:
            self.set_status(context, self.ERROR, reason='Deletion failed')
            return False
예제 #12
0
파일: node.py 프로젝트: KongJustin/senlin
    def store(self, context):
        '''Store the node record into database table.

        The invocation of DB API could be a node_create or a node_update,
        depending on whether node has an ID assigned.
        '''

        values = {
            'name': self.name,
            'physical_id': self.physical_id,
            'cluster_id': self.cluster_id,
            'profile_id': self.profile_id,
            'user': self.user,
            'project': self.project,
            'domain': self.domain,
            'index': self.index,
            'role': self.role,
            'init_time': self.init_time,
            'created_time': self.created_time,
            'updated_time': self.updated_time,
            'deleted_time': self.deleted_time,
            'status': self.status,
            'status_reason': self.status_reason,
            'meta_data': self.metadata,
            'data': self.data,
        }

        if self.id:
            db_api.node_update(context, self.id, values)
            event_mod.info(context, self, 'update')
        else:
            init_time = timeutils.utcnow()
            self.init_time = init_time
            values['init_time'] = init_time
            node = db_api.node_create(context, values)
            event_mod.info(context, self, 'create')
            self.id = node.id

        self._load_runtime_data(context)
        return self.id
예제 #13
0
파일: node.py 프로젝트: KongJustin/senlin
    def store(self, context):
        '''Store the node record into database table.

        The invocation of DB API could be a node_create or a node_update,
        depending on whether node has an ID assigned.
        '''

        values = {
            'name': self.name,
            'physical_id': self.physical_id,
            'cluster_id': self.cluster_id,
            'profile_id': self.profile_id,
            'user': self.user,
            'project': self.project,
            'domain': self.domain,
            'index': self.index,
            'role': self.role,
            'init_time': self.init_time,
            'created_time': self.created_time,
            'updated_time': self.updated_time,
            'deleted_time': self.deleted_time,
            'status': self.status,
            'status_reason': self.status_reason,
            'meta_data': self.metadata,
            'data': self.data,
        }

        if self.id:
            db_api.node_update(context, self.id, values)
            event_mod.info(context, self, 'update')
        else:
            init_time = timeutils.utcnow()
            self.init_time = init_time
            values['init_time'] = init_time
            node = db_api.node_create(context, values)
            event_mod.info(context, self, 'create')
            self.id = node.id

        self._load_runtime_data(context)
        return self.id
예제 #14
0
파일: base.py 프로젝트: zhouqiang-cl/senlin
    def set_status(self, result, reason=None):
        """Set action status based on return value from execute."""

        timestamp = wallclock()

        if result == self.RES_OK:
            status = self.SUCCEEDED
            ao.Action.mark_succeeded(self.context, self.id, timestamp)

        elif result == self.RES_ERROR:
            status = self.FAILED
            ao.Action.mark_failed(self.context, self.id, timestamp,
                                  reason or 'ERROR')

        elif result == self.RES_TIMEOUT:
            status = self.FAILED
            ao.Action.mark_failed(self.context, self.id, timestamp,
                                  reason or 'TIMEOUT')

        elif result == self.RES_CANCEL:
            status = self.CANCELLED
            ao.Action.mark_cancelled(self.context, self.id, timestamp)

        else:  # result == self.RES_RETRY:
            status = self.READY
            # Action failed at the moment, but can be retried
            # We abandon it and then notify other dispatchers to execute it
            ao.Action.abandon(self.context, self.id)
            dispatcher.start_action()

        if status == self.SUCCEEDED:
            EVENT.info(self, consts.PHASE_END, reason or 'SUCCEEDED')
        elif status == self.READY:
            EVENT.warning(self, consts.PHASE_ERROR, reason or 'RETRY')
        else:
            EVENT.error(self, consts.PHASE_ERROR, reason or 'ERROR')

        self.status = status
        self.status_reason = reason
예제 #15
0
파일: base.py 프로젝트: onesafe/senlin
    def set_status(self, result, reason=None):
        """Set action status based on return value from execute."""

        timestamp = wallclock()

        if result == self.RES_OK:
            status = self.SUCCEEDED
            db_api.action_mark_succeeded(self.context, self.id, timestamp)

        elif result == self.RES_ERROR:
            status = self.FAILED
            db_api.action_mark_failed(self.context, self.id, timestamp,
                                      reason=reason or 'ERROR')

        elif result == self.RES_TIMEOUT:
            status = self.FAILED
            db_api.action_mark_failed(self.context, self.id, timestamp,
                                      reason=reason or 'TIMEOUT')

        elif result == self.RES_CANCEL:
            status = self.CANCELLED
            db_api.action_mark_cancelled(self.context, self.id, timestamp)

        else:  # result == self.RES_RETRY:
            status = self.READY
            # Action failed at the moment, but can be retried
            # We abandon it and then notify other dispatchers to execute it
            db_api.action_abandon(self.context, self.id)

        if status == self.SUCCEEDED:
            EVENT.info(self.context, self, self.action, status, reason)
        elif status == self.READY:
            EVENT.warning(self.context, self, self.action, status, reason)
        else:
            EVENT.error(self.context, self, self.action, status, reason)

        self.status = status
        self.status_reason = reason
예제 #16
0
파일: cluster.py 프로젝트: tengqm/senlin
    def store(self, context):
        '''Store the cluster in database and return its ID.

        If the ID already exists, we do an update.
        '''

        values = {
            'name': self.name,
            'profile_id': self.profile_id,
            'user': self.user,
            'project': self.project,
            'domain': self.domain,
            'parent': self.parent,
            'init_time': self.init_time,
            'created_time': self.created_time,
            'updated_time': self.updated_time,
            'deleted_time': self.deleted_time,
            'size': self.size,
            'next_index': self.next_index,
            'timeout': self.timeout,
            'status': self.status,
            'status_reason': self.status_reason,
            'tags': self.tags,
            'data': self.data,
        }

        if self.id:
            db_api.cluster_update(context, self.id, values)
            event_mod.info(context, self, 'update')
        else:
            values['init_time'] = datetime.datetime.utcnow()
            cluster = db_api.cluster_create(context, values)
            self.id = cluster.id
            event_mod.info(context, self, 'create')

        self._load_runtime_data(context)
        return self.id