示例#1
0
文件: action.py 项目: Koulio/st2
def update_status(liveaction, new_status, result=None, publish=True):
    if liveaction.status == new_status:
        return liveaction

    old_status = liveaction.status

    liveaction = action_utils.update_liveaction_status(
        status=new_status, result=result, liveaction_id=liveaction.id, publish=False
    )

    action_execution = executions.update_execution(liveaction)

    msg = "The status of action execution is changed from %s to %s. " "<LiveAction.id=%s, ActionExecution.id=%s>" % (
        old_status,
        new_status,
        liveaction.id,
        action_execution.id,
    )

    extra = {"action_execution_db": action_execution, "liveaction_db": liveaction}

    LOG.audit(msg, extra=extra)
    LOG.info(msg)

    if publish:
        LiveAction.publish_status(liveaction)

    return liveaction
示例#2
0
def update_status(liveaction, new_status, result=None, publish=True):
    if liveaction.status == new_status:
        return liveaction

    old_status = liveaction.status

    liveaction = action_utils.update_liveaction_status(
        status=new_status,
        result=result,
        liveaction_id=liveaction.id,
        publish=False)

    action_execution = executions.update_execution(liveaction)

    msg = ('The status of action execution is changed from %s to %s. '
           '<LiveAction.id=%s, ActionExecution.id=%s>' %
           (old_status, new_status, liveaction.id, action_execution.id))

    extra = {
        'action_execution_db': action_execution,
        'liveaction_db': liveaction
    }

    LOG.audit(msg, extra=extra)
    LOG.info(msg)

    if publish:
        LiveAction.publish_status(liveaction)

    return liveaction
示例#3
0
文件: handler.py 项目: tzmvp/st2
    def _update_to_scheduled(liveaction_db, execution_queue_item_db):
        liveaction_id = str(liveaction_db.id)
        queue_item_id = str(execution_queue_item_db.id)

        extra = {
            'liveaction_id': liveaction_id,
            'liveaction_status': liveaction_db.status,
            'queue_item_id': queue_item_id
        }

        # Update liveaction status to "scheduled".
        LOG.info('Liveaction (%s) Status Update to Scheduled 1: %s (%s)',
                liveaction_id, liveaction_db.status, queue_item_id, extra=extra)

        if liveaction_db.status in [action_constants.LIVEACTION_STATUS_REQUESTED,
                                    action_constants.LIVEACTION_STATUS_DELAYED]:
            liveaction_db = action_service.update_status(
                liveaction_db, action_constants.LIVEACTION_STATUS_SCHEDULED, publish=False)

        # Publish the "scheduled" status here manually. Otherwise, there could be a
        # race condition with the update of the action_execution_db if the execution
        # of the liveaction completes first.
        LiveAction.publish_status(liveaction_db)

        extra['liveaction_status'] = liveaction_db.status

        # Delete execution queue entry only after status is published.
        ActionExecutionSchedulingQueue.delete(execution_queue_item_db)
        LOG.info('Liveaction (%s) Status Update to Scheduled 2: %s (%s)',
                liveaction_id, liveaction_db.status, queue_item_id)
示例#4
0
文件: handler.py 项目: mahak/st2
    def _update_to_scheduled(liveaction_db, execution_queue_item_db):
        liveaction_id = str(liveaction_db.id)
        queue_item_id = str(execution_queue_item_db.id)

        extra = {
            'liveaction_id': liveaction_id,
            'liveaction_status': liveaction_db.status,
            'queue_item_id': queue_item_id
        }

        # Update liveaction status to "scheduled".
        LOG.info('Liveaction (%s) Status Update to Scheduled 1: %s (%s)',
                liveaction_id, liveaction_db.status, queue_item_id, extra=extra)

        if liveaction_db.status in [action_constants.LIVEACTION_STATUS_REQUESTED,
                                    action_constants.LIVEACTION_STATUS_DELAYED]:
            liveaction_db = action_service.update_status(
                liveaction_db, action_constants.LIVEACTION_STATUS_SCHEDULED, publish=False)

        # Publish the "scheduled" status here manually. Otherwise, there could be a
        # race condition with the update of the action_execution_db if the execution
        # of the liveaction completes first.
        LiveAction.publish_status(liveaction_db)

        extra['liveaction_status'] = liveaction_db.status

        # Delete execution queue entry only after status is published.
        ActionExecutionSchedulingQueue.delete(execution_queue_item_db)
        LOG.info('Liveaction (%s) Status Update to Scheduled 2: %s (%s)',
                liveaction_id, liveaction_db.status, queue_item_id)
示例#5
0
def update_liveaction_status(status=None,
                             result=None,
                             context=None,
                             end_timestamp=None,
                             liveaction_id=None,
                             runner_info=None,
                             liveaction_db=None,
                             publish=True):
    """
        Update the status of the specified LiveAction to the value provided in
        new_status.

        The LiveAction may be specified using either liveaction_id, or as an
        liveaction_db instance.
    """

    if (liveaction_id is None) and (liveaction_db is None):
        raise ValueError(
            'Must specify an liveaction_id or an liveaction_db when '
            'calling update_LiveAction_status')

    if liveaction_db is None:
        liveaction_db = get_liveaction_by_id(liveaction_id)

    if status not in LIVEACTION_STATUSES:
        raise ValueError(
            'Attempting to set status for LiveAction "%s" '
            'to unknown status string. Unknown status is "%s"', liveaction_db,
            status)

    extra = {'liveaction_db': liveaction_db}
    LOG.debug('Updating ActionExection: "%s" with status="%s"',
              liveaction_db.id,
              status,
              extra=extra)

    old_status = liveaction_db.status
    liveaction_db.status = status

    if result:
        liveaction_db.result = result

    if context:
        liveaction_db.context.update(context)

    if end_timestamp:
        liveaction_db.end_timestamp = end_timestamp

    if runner_info:
        liveaction_db.runner_info = runner_info

    liveaction_db = LiveAction.add_or_update(liveaction_db)

    LOG.debug('Updated status for LiveAction object.', extra=extra)

    if publish and status != old_status:
        LiveAction.publish_status(liveaction_db)
        LOG.debug('Published status for LiveAction object.', extra=extra)

    return liveaction_db
示例#6
0
文件: action.py 项目: jonico/st2
def update_status(liveaction, new_status, publish=True):
    if liveaction.status == new_status:
        return liveaction

    old_status = liveaction.status

    liveaction = action_utils.update_liveaction_status(
        status=new_status, liveaction_id=liveaction.id, publish=False)

    action_execution = executions.update_execution(liveaction)

    msg = ('The status of action execution is changed from %s to %s. '
           '<LiveAction.id=%s, ActionExecution.id=%s>' % (old_status,
           new_status, liveaction.id, action_execution.id))

    extra = {
        'action_execution_db': action_execution,
        'liveaction_db': liveaction
    }

    LOG.audit(msg, extra=extra)
    LOG.info(msg)

    if publish:
        LiveAction.publish_status(liveaction)

    return liveaction
示例#7
0
    def _update_to_scheduled(liveaction_db, execution_queue_item_db):
        action_execution_id = str(execution_queue_item_db.action_execution_id)
        liveaction_id = str(execution_queue_item_db.liveaction_id)
        queue_item_id = str(execution_queue_item_db.id)
        extra = {'queue_item_id': queue_item_id}

        # Update liveaction status to "scheduled".
        LOG.info(
            '[%s] Liveaction "%s" with status "%s" is updated to status "scheduled."',
            action_execution_id,
            liveaction_id,
            liveaction_db.status,
            extra=extra)

        if liveaction_db.status in [
                action_constants.LIVEACTION_STATUS_REQUESTED,
                action_constants.LIVEACTION_STATUS_DELAYED
        ]:
            liveaction_db = action_service.update_status(
                liveaction_db,
                action_constants.LIVEACTION_STATUS_SCHEDULED,
                publish=False)

        # Publish the "scheduled" status here manually. Otherwise, there could be a
        # race condition with the update of the action_execution_db if the execution
        # of the liveaction completes first.
        LiveAction.publish_status(liveaction_db)

        # Delete execution queue entry only after status is published.
        ActionExecutionSchedulingQueue.delete(execution_queue_item_db)
示例#8
0
文件: action_db.py 项目: ipv1337/st2
def update_liveaction_status(
    status=None,
    result=None,
    context=None,
    end_timestamp=None,
    liveaction_id=None,
    runner_info=None,
    liveaction_db=None,
    publish=True,
):
    """
        Update the status of the specified LiveAction to the value provided in
        new_status.

        The LiveAction may be specified using either liveaction_id, or as an
        liveaction_db instance.
    """

    if (liveaction_id is None) and (liveaction_db is None):
        raise ValueError("Must specify an liveaction_id or an liveaction_db when " "calling update_LiveAction_status")

    if liveaction_db is None:
        liveaction_db = get_liveaction_by_id(liveaction_id)

    if status not in LIVEACTION_STATUSES:
        raise ValueError(
            'Attempting to set status for LiveAction "%s" ' 'to unknown status string. Unknown status is "%s"',
            liveaction_db,
            status,
        )

    extra = {"liveaction_db": liveaction_db}
    LOG.debug('Updating ActionExection: "%s" with status="%s"', liveaction_db.id, status, extra=extra)

    old_status = liveaction_db.status
    liveaction_db.status = status

    if result:
        liveaction_db.result = result

    if context:
        liveaction_db.context.update(context)

    if end_timestamp:
        liveaction_db.end_timestamp = end_timestamp

    if runner_info:
        liveaction_db.runner_info = runner_info

    liveaction_db = LiveAction.add_or_update(liveaction_db)

    LOG.debug("Updated status for LiveAction object.", extra=extra)

    if publish and status != old_status:
        LiveAction.publish_status(liveaction_db)
        LOG.debug("Published status for LiveAction object.", extra=extra)

    return liveaction_db
示例#9
0
文件: scheduler.py 项目: rlugojr/st2
    def process(self, request):
        """Schedules the LiveAction and publishes the request
        to the appropriate action runner(s).

        LiveAction in statuses other than "requested" are ignored.

        :param request: Action execution request.
        :type request: ``st2common.models.db.liveaction.LiveActionDB``
        """

        if request.status != action_constants.LIVEACTION_STATUS_REQUESTED:
            LOG.info(
                '%s is ignoring %s (id=%s) with "%s" status.',
                self.__class__.__name__,
                type(request),
                request.id,
                request.status,
            )
            return

        try:
            liveaction_db = action_utils.get_liveaction_by_id(request.id)
        except StackStormDBObjectNotFoundError:
            LOG.exception("Failed to find liveaction %s in the database.", request.id)
            raise

        # Apply policies defined for the action.
        liveaction_db = self._apply_pre_run_policies(liveaction_db=liveaction_db)

        # Exit if the status of the request is no longer runnable.
        # The status could have be changed by one of the policies.
        if liveaction_db.status not in [
            action_constants.LIVEACTION_STATUS_REQUESTED,
            action_constants.LIVEACTION_STATUS_SCHEDULED,
        ]:
            LOG.info(
                '%s is ignoring %s (id=%s) with "%s" status after policies are applied.',
                self.__class__.__name__,
                type(request),
                request.id,
                liveaction_db.status,
            )
            return

        # Update liveaction status to "scheduled".
        if liveaction_db.status == action_constants.LIVEACTION_STATUS_REQUESTED:
            liveaction_db = action_service.update_status(
                liveaction_db, action_constants.LIVEACTION_STATUS_SCHEDULED, publish=False
            )

        # Publish the "scheduled" status here manually. Otherwise, there could be a
        # race condition with the update of the action_execution_db if the execution
        # of the liveaction completes first.
        LiveAction.publish_status(liveaction_db)
示例#10
0
    def test_no_double_entries(self):
        self.reset()

        liveaction_db = self._create_liveaction_db()

        LiveAction.publish_status(liveaction_db)
        LiveAction.publish_status(liveaction_db)

        schedule_q_db = self.scheduling_queue._get_next_execution()
        self.assertIsNotNone(schedule_q_db)

        schedule_q_db = self.scheduling_queue._get_next_execution()
        self.assertIsNone(schedule_q_db)
示例#11
0
    def test_no_double_entries(self):
        self.reset()

        liveaction_db = self._create_liveaction_db()

        LiveAction.publish_status(liveaction_db)
        LiveAction.publish_status(liveaction_db)

        schedule_q_db = self.scheduling_queue._get_next_execution()
        self.assertIsNotNone(schedule_q_db)

        schedule_q_db = self.scheduling_queue._get_next_execution()
        self.assertIsNone(schedule_q_db)
示例#12
0
    def test_no_processing_of_non_requested_actions(self):
        self.reset()

        for status in action_constants.LIVEACTION_STATUSES:
            liveaction_db = self._create_liveaction_db(status=status)

            LiveAction.publish_status(liveaction_db)

            schedule_q_db = self.scheduling_queue._get_next_execution()

            if status is action_constants.LIVEACTION_STATUS_REQUESTED:
                self.assertIsNotNone(schedule_q_db)
            else:
                self.assertIsNone(schedule_q_db)
    def process(self, request):
        """Schedules the LiveAction and publishes the request
        to the appropriate action runner(s).

        LiveAction in statuses other than "requested" are ignored.

        :param request: Action execution request.
        :type request: ``st2common.models.db.liveaction.LiveActionDB``
        """

        if request.status != action_constants.LIVEACTION_STATUS_REQUESTED:
            LOG.info('%s is ignoring %s (id=%s) with "%s" status.',
                     self.__class__.__name__, type(request), request.id,
                     request.status)
            return

        try:
            liveaction_db = action_utils.get_liveaction_by_id(request.id)
        except StackStormDBObjectNotFoundError:
            LOG.exception('Failed to find liveaction %s in the database.',
                          request.id)
            raise

        # Apply policies defined for the action.
        liveaction_db = self._apply_pre_run_policies(
            liveaction_db=liveaction_db)

        # Exit if the status of the request is no longer runnable.
        # The status could have be changed by one of the policies.
        if liveaction_db.status not in [
                action_constants.LIVEACTION_STATUS_REQUESTED,
                action_constants.LIVEACTION_STATUS_SCHEDULED
        ]:
            LOG.info(
                '%s is ignoring %s (id=%s) with "%s" status after policies are applied.',
                self.__class__.__name__, type(request), request.id,
                liveaction_db.status)
            return

        # Update liveaction status to "scheduled".
        if liveaction_db.status == action_constants.LIVEACTION_STATUS_REQUESTED:
            liveaction_db = action_service.update_status(
                liveaction_db,
                action_constants.LIVEACTION_STATUS_SCHEDULED,
                publish=False)

        # Publish the "scheduled" status here manually. Otherwise, there could be a
        # race condition with the update of the action_execution_db if the execution
        # of the liveaction completes first.
        LiveAction.publish_status(liveaction_db)
示例#14
0
    def test_no_processing_of_non_requested_actions(self):
        self.reset()

        for status in action_constants.LIVEACTION_STATUSES:
            liveaction_db = self._create_liveaction_db(status=status)

            LiveAction.publish_status(liveaction_db)

            schedule_q_db = self.scheduling_queue._get_next_execution()

            if status is action_constants.LIVEACTION_STATUS_REQUESTED:
                self.assertIsNotNone(schedule_q_db)
            else:
                self.assertIsNone(schedule_q_db)
示例#15
0
文件: action.py 项目: rush-skills/st2
def update_status(
    liveaction,
    new_status,
    result=None,
    publish=True,
    set_result_size=False,
    context=None,
):
    if liveaction.status == new_status:
        return liveaction

    old_status = liveaction.status

    updates = {
        "liveaction_id": liveaction.id,
        "status": new_status,
        "result": result,
        "publish": False,
        "context": context,
    }

    if new_status in action_constants.LIVEACTION_COMPLETED_STATES:
        updates["end_timestamp"] = date_utils.get_datetime_utc_now()

    liveaction = action_utils.update_liveaction_status(**updates)
    action_execution = executions.update_execution(
        liveaction, set_result_size=set_result_size)

    msg = ("The status of action execution is changed from %s to %s. "
           "<LiveAction.id=%s, ActionExecution.id=%s>" %
           (old_status, new_status, liveaction.id, action_execution.id))

    extra = {
        "action_execution_db": action_execution,
        "liveaction_db": liveaction
    }

    LOG.audit(msg, extra=extra)
    LOG.info(msg)

    # Invoke post run if liveaction status is completed or paused.
    if (new_status in action_constants.LIVEACTION_COMPLETED_STATES
            or new_status == action_constants.LIVEACTION_STATUS_PAUSED):
        runners_utils.invoke_post_run(liveaction)

    if publish:
        LiveAction.publish_status(liveaction)

    return liveaction
示例#16
0
    def test_processing_when_task_completed(self, mock_execution_queue_delete, mock_action_service):
        self.reset()

        liveaction_db = self._create_liveaction_db()

        LiveAction.publish_status(liveaction_db)
        liveaction_db.status = action_constants.LIVEACTION_STATUS_CANCELED
        LiveAction.add_or_update(liveaction_db)

        schedule_q_db = self.scheduling_queue._get_next_execution()
        scheduling_queue.get_handler()._handle_execution(schedule_q_db)

        mock_action_service.update_status.assert_not_called()
        mock_execution_queue_delete.assert_called_once()
        ActionExecutionSchedulingQueue.delete(schedule_q_db)
示例#17
0
    def test_processing_when_task_completed(self, mock_execution_queue_delete, mock_action_service):
        self.reset()

        liveaction_db = self._create_liveaction_db()

        LiveAction.publish_status(liveaction_db)
        liveaction_db.status = action_constants.LIVEACTION_STATUS_CANCELED
        LiveAction.add_or_update(liveaction_db)

        schedule_q_db = self.scheduling_queue._get_next_execution()
        scheduling_queue.get_handler()._handle_execution(schedule_q_db)

        mock_action_service.update_status.assert_not_called()
        mock_execution_queue_delete.assert_called_once()
        ActionExecutionSchedulingQueue.delete(schedule_q_db)
示例#18
0
def publish_request(liveaction, execution):
    """
    Publish an action execution.

    :return: (liveaction, execution)
    :rtype: tuple
    """
    # Assume that this is a creation.
    LiveAction.publish_create(liveaction)
    LiveAction.publish_status(liveaction)
    ActionExecution.publish_create(execution)

    extra = {'liveaction_db': liveaction, 'execution_db': execution}
    LOG.audit('Action execution requested. LiveAction.id=%s, ActionExecution.id=%s' %
              (liveaction.id, execution.id), extra=extra)

    return liveaction, execution
示例#19
0
文件: action.py 项目: LindsayHill/st2
def publish_request(liveaction, execution):
    """
    Publish an action execution.

    :return: (liveaction, execution)
    :rtype: tuple
    """
    # Assume that this is a creation.
    LiveAction.publish_create(liveaction)
    LiveAction.publish_status(liveaction)
    ActionExecution.publish_create(execution)

    extra = {'liveaction_db': liveaction, 'execution_db': execution}
    LOG.audit('Action execution requested. LiveAction.id=%s, ActionExecution.id=%s' %
              (liveaction.id, execution.id), extra=extra)

    return liveaction, execution
示例#20
0
文件: action.py 项目: sinnershiki/st2
def publish_request(liveaction, execution):
    """
    Publish an action execution.

    :return: (liveaction, execution)
    :rtype: tuple
    """
    # Assume that this is a creation.
    LiveAction.publish_create(liveaction)
    LiveAction.publish_status(liveaction)
    ActionExecution.publish_create(execution)

    # TODO: This results in two queries, optimize it
    #  extra = {'liveaction_db': liveaction, 'execution_db': execution}
    extra = {}
    LOG.audit('Action execution requested. LiveAction.id=%s, ActionExecution.id=%s' %
              (liveaction.id, execution.id), extra=extra)

    return liveaction, execution
示例#21
0
文件: action.py 项目: StackStorm/st2
def publish_request(liveaction, execution):
    """
    Publish an action execution.

    :return: (liveaction, execution)
    :rtype: tuple
    """
    # Assume that this is a creation.
    LiveAction.publish_create(liveaction)
    LiveAction.publish_status(liveaction)
    ActionExecution.publish_create(execution)

    # TODO: This results in two queries, optimize it
    #  extra = {'liveaction_db': liveaction, 'execution_db': execution}
    extra = {}
    LOG.audit('Action execution requested. LiveAction.id=%s, ActionExecution.id=%s' %
              (liveaction.id, execution.id), extra=extra)

    return liveaction, execution
示例#22
0
文件: scheduler.py 项目: bsyk/st2
    def process(self, request):
        """Schedules the LiveAction and publishes the request
        to the appropriate action runner(s).

        LiveAction in statuses other than "requested" are ignored.

        :param request: Action execution request.
        :type request: ``st2common.models.db.liveaction.LiveActionDB``
        """

        if request.status != action_constants.LIVEACTION_STATUS_REQUESTED:
            LOG.info('%s is ignoring %s (id=%s) with "%s" status.',
                     self.__class__.__name__, type(request), request.id, request.status)
            return

        try:
            liveaction_db = action_utils.get_liveaction_by_id(request.id)
        except StackStormDBObjectNotFoundError:
            LOG.exception('Failed to find liveaction %s in the database.', request.id)
            raise

        # Update liveaction status to "scheduled"
        liveaction_db = action_utils.update_liveaction_status(
            status=action_constants.LIVEACTION_STATUS_SCHEDULED,
            liveaction_id=liveaction_db.id,
            publish=False)

        action_execution_db = executions.update_execution(liveaction_db)

        # Publish the "scheduled" status here manually. Otherwise, there could be a
        # race condition with the update of the action_execution_db if the execution
        # of the liveaction completes first.
        LiveAction.publish_status(liveaction_db)

        extra = {'action_execution_db': action_execution_db, 'liveaction_db': liveaction_db}
        LOG.audit('Scheduled action execution.', extra=extra)

        # the extra field will not be shown in non-audit logs so temporarily log at info.
        LOG.info('Scheduled {~}action_execution: %s / {~}live_action: %s with "%s" status.',
                 action_execution_db.id, liveaction_db.id, request.status)
示例#23
0
文件: action.py 项目: StackStorm/st2
def update_status(liveaction, new_status, result=None, publish=True):
    if liveaction.status == new_status:
        return liveaction

    old_status = liveaction.status

    updates = {
        'liveaction_id': liveaction.id,
        'status': new_status,
        'result': result,
        'publish': False
    }

    if new_status in action_constants.LIVEACTION_COMPLETED_STATES:
        updates['end_timestamp'] = date_utils.get_datetime_utc_now()

    liveaction = action_utils.update_liveaction_status(**updates)
    action_execution = executions.update_execution(liveaction)

    msg = ('The status of action execution is changed from %s to %s. '
           '<LiveAction.id=%s, ActionExecution.id=%s>' % (old_status,
           new_status, liveaction.id, action_execution.id))

    extra = {
        'action_execution_db': action_execution,
        'liveaction_db': liveaction
    }

    LOG.audit(msg, extra=extra)
    LOG.info(msg)

    # Invoke post run if liveaction status is completed or paused.
    if (new_status in action_constants.LIVEACTION_COMPLETED_STATES or
            new_status == action_constants.LIVEACTION_STATUS_PAUSED):
        runners_utils.invoke_post_run(liveaction)

    if publish:
        LiveAction.publish_status(liveaction)

    return liveaction
示例#24
0
def update_status(liveaction, new_status, result=None, publish=True):
    if liveaction.status == new_status:
        return liveaction

    old_status = liveaction.status

    updates = {
        'liveaction_id': liveaction.id,
        'status': new_status,
        'result': result,
        'publish': False
    }

    if new_status in action_constants.LIVEACTION_COMPLETED_STATES:
        updates['end_timestamp'] = date_utils.get_datetime_utc_now()

    liveaction = action_utils.update_liveaction_status(**updates)
    action_execution = executions.update_execution(liveaction)

    msg = ('The status of action execution is changed from %s to %s. '
           '<LiveAction.id=%s, ActionExecution.id=%s>' %
           (old_status, new_status, liveaction.id, action_execution.id))

    extra = {
        'action_execution_db': action_execution,
        'liveaction_db': liveaction
    }

    LOG.audit(msg, extra=extra)
    LOG.info(msg)

    # Invoke post run if liveaction status is completed or paused.
    if (new_status in action_constants.LIVEACTION_COMPLETED_STATES
            or new_status == action_constants.LIVEACTION_STATUS_PAUSED):
        runners_utils.invoke_post_run(liveaction)

    if publish:
        LiveAction.publish_status(liveaction)

    return liveaction
示例#25
0
文件: action.py 项目: ruslantum/st2
def request(liveaction):
    """
    Request an action execution.

    :return: (liveaction, execution)
    :rtype: tuple
    """
    # Use the user context from the parent action execution. Subtasks in a workflow
    # action can be invoked by a system user and so we want to use the user context
    # from the original workflow action.
    if getattr(liveaction, "context", None) and "parent" in liveaction.context:
        parent_user = liveaction.context["parent"].get("user", None)
        if parent_user:
            liveaction.context["user"] = parent_user

    # Validate action.
    action_db = action_utils.get_action_by_ref(liveaction.action)
    if not action_db:
        raise ValueError('Action "%s" cannot be found.' % liveaction.action)
    if not action_db.enabled:
        raise ValueError('Unable to execute. Action "%s" is disabled.' % liveaction.action)

    runnertype_db = action_utils.get_runnertype_by_name(action_db.runner_type["name"])

    if not hasattr(liveaction, "parameters"):
        liveaction.parameters = dict()

    # Validate action parameters.
    schema = util_schema.get_parameter_schema(action_db)
    validator = util_schema.get_validator()
    util_schema.validate(liveaction.parameters, schema, validator, use_default=True)

    # validate that no immutable params are being overriden. Although possible to
    # ignore the override it is safer to inform the user to avoid surprises.
    immutables = _get_immutable_params(action_db.parameters)
    immutables.extend(_get_immutable_params(runnertype_db.runner_parameters))
    overridden_immutables = [p for p in six.iterkeys(liveaction.parameters) if p in immutables]
    if len(overridden_immutables) > 0:
        raise ValueError("Override of immutable parameter(s) %s is unsupported." % str(overridden_immutables))

    # Set notification settings for action.
    # XXX: There are cases when we don't want notifications to be sent for a particular
    # execution. So we should look at liveaction.parameters['notify']
    # and not set liveaction.notify.
    if action_db.notify:
        liveaction.notify = action_db.notify

    # Write to database and send to message queue.
    liveaction.status = action_constants.LIVEACTION_STATUS_REQUESTED
    liveaction.start_timestamp = date_utils.get_datetime_utc_now()

    # Publish creation after both liveaction and actionexecution are created.
    liveaction = LiveAction.add_or_update(liveaction, publish=False)
    execution = executions.create_execution_object(liveaction, publish=False)

    # Assume that this is a creation.
    LiveAction.publish_create(liveaction)
    LiveAction.publish_status(liveaction)
    ActionExecution.publish_create(execution)

    extra = {"liveaction_db": liveaction, "execution_db": execution}
    LOG.audit(
        "Action execution requested. LiveAction.id=%s, ActionExecution.id=%s" % (liveaction.id, execution.id),
        extra=extra,
    )

    return liveaction, execution
示例#26
0
文件: action.py 项目: jonico/st2
def request(liveaction):
    """
    Request an action execution.

    :return: (liveaction, execution)
    :rtype: tuple
    """
    # Use the user context from the parent action execution. Subtasks in a workflow
    # action can be invoked by a system user and so we want to use the user context
    # from the original workflow action.
    if getattr(liveaction, 'context', None) and 'parent' in liveaction.context:
        parent_user = liveaction.context['parent'].get('user', None)
        if parent_user:
            liveaction.context['user'] = parent_user

    # Validate action.
    action_db = action_utils.get_action_by_ref(liveaction.action)
    if not action_db:
        raise ValueError('Action "%s" cannot be found.' % liveaction.action)
    if not action_db.enabled:
        raise ValueError('Unable to execute. Action "%s" is disabled.' % liveaction.action)

    runnertype_db = action_utils.get_runnertype_by_name(action_db.runner_type['name'])

    if not hasattr(liveaction, 'parameters'):
        liveaction.parameters = dict()

    # Validate action parameters.
    schema = util_schema.get_parameter_schema(action_db)
    validator = util_schema.get_validator()
    util_schema.validate(liveaction.parameters, schema, validator, use_default=True)

    # validate that no immutable params are being overriden. Although possible to
    # ignore the override it is safer to inform the user to avoid surprises.
    immutables = _get_immutable_params(action_db.parameters)
    immutables.extend(_get_immutable_params(runnertype_db.runner_parameters))
    overridden_immutables = [p for p in six.iterkeys(liveaction.parameters) if p in immutables]
    if len(overridden_immutables) > 0:
        raise ValueError('Override of immutable parameter(s) %s is unsupported.'
                         % str(overridden_immutables))

    # Set notification settings for action.
    # XXX: There are cases when we don't want notifications to be sent for a particular
    # execution. So we should look at liveaction.parameters['notify']
    # and not set liveaction.notify.
    if action_db.notify:
        liveaction.notify = action_db.notify

    # Write to database and send to message queue.
    liveaction.status = action_constants.LIVEACTION_STATUS_REQUESTED
    liveaction.start_timestamp = date_utils.get_datetime_utc_now()

    # Publish creation after both liveaction and actionexecution are created.
    liveaction = LiveAction.add_or_update(liveaction, publish=False)

    # Get trace_db if it exists. This could throw. If it throws, we have to cleanup
    # liveaction object so we don't see things in requested mode.
    trace_db = None
    try:
        _, trace_db = trace_service.get_trace_db_by_live_action(liveaction)
    except StackStormDBObjectNotFoundError as e:
        _cleanup_liveaction(liveaction)
        raise TraceNotFoundException(str(e))

    execution = executions.create_execution_object(liveaction, publish=False)

    if trace_db:
        trace_service.add_or_update_given_trace_db(
            trace_db=trace_db,
            action_executions=[str(execution.id)])

    # Assume that this is a creation.
    LiveAction.publish_create(liveaction)
    LiveAction.publish_status(liveaction)
    ActionExecution.publish_create(execution)

    extra = {'liveaction_db': liveaction, 'execution_db': execution}
    LOG.audit('Action execution requested. LiveAction.id=%s, ActionExecution.id=%s' %
              (liveaction.id, execution.id), extra=extra)

    return liveaction, execution
示例#27
0
文件: action_db.py 项目: nzlosh/st2
def update_liveaction_status(status=None, result=None, context=None, end_timestamp=None,
                             liveaction_id=None, runner_info=None, liveaction_db=None,
                             publish=True):
    """
        Update the status of the specified LiveAction to the value provided in
        new_status.

        The LiveAction may be specified using either liveaction_id, or as an
        liveaction_db instance.
    """

    if (liveaction_id is None) and (liveaction_db is None):
        raise ValueError('Must specify an liveaction_id or an liveaction_db when '
                         'calling update_LiveAction_status')

    if liveaction_db is None:
        liveaction_db = get_liveaction_by_id(liveaction_id)

    if status not in LIVEACTION_STATUSES:
        raise ValueError('Attempting to set status for LiveAction "%s" '
                         'to unknown status string. Unknown status is "%s"'
                         % (liveaction_db, status))

    if result and cfg.CONF.system.validate_output_schema and status == LIVEACTION_STATUS_SUCCEEDED:
        action_db = get_action_by_ref(liveaction_db.action)
        runner_db = get_runnertype_by_name(action_db.runner_type['name'])
        result, status = output_schema.validate_output(
            runner_db.output_schema,
            action_db.output_schema,
            result,
            status,
            runner_db.output_key,
        )

    # If liveaction_db status is set then we need to decrement the counter
    # because it is transitioning to a new state
    if liveaction_db.status:
        get_driver().dec_counter('action.executions.%s' % (liveaction_db.status))

    # If status is provided then we need to increment the timer because the action
    # is transitioning into this new state
    if status:
        get_driver().inc_counter('action.executions.%s' % (status))

    extra = {'liveaction_db': liveaction_db}
    LOG.debug('Updating ActionExection: "%s" with status="%s"', liveaction_db.id, status,
              extra=extra)

    # If liveaction is already canceled, then do not allow status to be updated.
    if liveaction_db.status == LIVEACTION_STATUS_CANCELED and status != LIVEACTION_STATUS_CANCELED:
        LOG.info('Unable to update ActionExecution "%s" with status="%s". '
                 'ActionExecution is already canceled.', liveaction_db.id, status, extra=extra)
        return liveaction_db

    old_status = liveaction_db.status
    liveaction_db.status = status

    if result:
        liveaction_db.result = result

    if context:
        liveaction_db.context.update(context)

    if end_timestamp:
        liveaction_db.end_timestamp = end_timestamp

    if runner_info:
        liveaction_db.runner_info = runner_info

    # TODO: This is not efficient. Perform direct partial update and only update
    # manipulated fields
    liveaction_db = LiveAction.add_or_update(liveaction_db)

    LOG.debug('Updated status for LiveAction object.', extra=extra)

    if publish and status != old_status:
        LiveAction.publish_status(liveaction_db)
        LOG.debug('Published status for LiveAction object.', extra=extra)

    return liveaction_db
示例#28
0
def request(liveaction):
    """
    Request an action execution.

    :return: (liveaction, execution)
    :rtype: tuple
    """
    # Use the user context from the parent action execution. Subtasks in a workflow
    # action can be invoked by a system user and so we want to use the user context
    # from the original workflow action.
    if getattr(liveaction, 'context', None) and 'parent' in liveaction.context:
        parent = LiveAction.get_by_id(liveaction.context['parent'])
        liveaction.context['user'] = getattr(parent, 'context',
                                             dict()).get('user')

    # Validate action.
    action_db = action_utils.get_action_by_ref(liveaction.action)
    if not action_db:
        raise ValueError('Action "%s" cannot be found.' % liveaction.action)
    if not action_db.enabled:
        raise ValueError('Unable to execute. Action "%s" is disabled.' %
                         liveaction.action)

    runnertype_db = action_utils.get_runnertype_by_name(
        action_db.runner_type['name'])

    if not hasattr(liveaction, 'parameters'):
        liveaction.parameters = dict()

    # Validate action parameters.
    schema = util_schema.get_parameter_schema(action_db)
    validator = util_schema.get_validator()
    util_schema.validate(liveaction.parameters,
                         schema,
                         validator,
                         use_default=True)

    # validate that no immutable params are being overriden. Although possible to
    # ignore the override it is safer to inform the user to avoid surprises.
    immutables = _get_immutable_params(action_db.parameters)
    immutables.extend(_get_immutable_params(runnertype_db.runner_parameters))
    overridden_immutables = [
        p for p in six.iterkeys(liveaction.parameters) if p in immutables
    ]
    if len(overridden_immutables) > 0:
        raise ValueError(
            'Override of immutable parameter(s) %s is unsupported.' %
            str(overridden_immutables))

    # Set notification settings for action.
    # XXX: There are cases when we don't want notifications to be sent for a particular
    # execution. So we should look at liveaction.parameters['notify']
    # and not set liveaction.notify.
    if action_db.notify:
        liveaction.notify = action_db.notify

    # Write to database and send to message queue.
    liveaction.status = action_constants.LIVEACTION_STATUS_REQUESTED
    liveaction.start_timestamp = date_utils.get_datetime_utc_now()

    # Publish creation after both liveaction and actionexecution are created.
    liveaction = LiveAction.add_or_update(liveaction, publish=False)
    execution = executions.create_execution_object(liveaction, publish=False)

    # Assume that this is a creation.
    LiveAction.publish_create(liveaction)
    LiveAction.publish_status(liveaction)
    ActionExecution.publish_create(execution)

    extra = {'liveaction_db': liveaction, 'execution_db': execution}
    LOG.audit(
        'Action execution requested. LiveAction.id=%s, ActionExecution.id=%s' %
        (liveaction.id, execution.id),
        extra=extra)

    return liveaction, execution
示例#29
0
文件: action_db.py 项目: lyandut/st2
def update_liveaction_status(status=None, result=None, context=None, end_timestamp=None,
                             liveaction_id=None, runner_info=None, liveaction_db=None,
                             publish=True):
    """
        Update the status of the specified LiveAction to the value provided in
        new_status.

        The LiveAction may be specified using either liveaction_id, or as an
        liveaction_db instance.
    """

    if (liveaction_id is None) and (liveaction_db is None):
        raise ValueError('Must specify an liveaction_id or an liveaction_db when '
                         'calling update_LiveAction_status')

    if liveaction_db is None:
        liveaction_db = get_liveaction_by_id(liveaction_id)

    if status not in LIVEACTION_STATUSES:
        raise ValueError('Attempting to set status for LiveAction "%s" '
                         'to unknown status string. Unknown status is "%s"',
                         liveaction_db, status)

    # If liveaction_db status is set then we need to decrement the counter
    # because it is transitioning to a new state
    if liveaction_db.status:
        get_driver().dec_counter(
            format_metrics_key(
                liveaction_db=liveaction_db,
                key='action.%s' % liveaction_db.status
            )
        )

    # If status is provided then we need to increment the timer because the action
    # is transitioning into this new state
    if status:
        get_driver().inc_counter(
            format_metrics_key(
                liveaction_db=liveaction_db,
                key='action.%s' % status
            )
        )

    extra = {'liveaction_db': liveaction_db}
    LOG.debug('Updating ActionExection: "%s" with status="%s"', liveaction_db.id, status,
              extra=extra)

    # If liveaction is already canceled, then do not allow status to be updated.
    if liveaction_db.status == LIVEACTION_STATUS_CANCELED and status != LIVEACTION_STATUS_CANCELED:
        LOG.info('Unable to update ActionExecution "%s" with status="%s". '
                 'ActionExecution is already canceled.', liveaction_db.id, status, extra=extra)
        return liveaction_db

    old_status = liveaction_db.status
    liveaction_db.status = status

    if result:
        liveaction_db.result = result

    if context:
        liveaction_db.context.update(context)

    if end_timestamp:
        liveaction_db.end_timestamp = end_timestamp

    if runner_info:
        liveaction_db.runner_info = runner_info

    liveaction_db = LiveAction.add_or_update(liveaction_db)

    LOG.debug('Updated status for LiveAction object.', extra=extra)

    if publish and status != old_status:
        LiveAction.publish_status(liveaction_db)
        LOG.debug('Published status for LiveAction object.', extra=extra)

    return liveaction_db
示例#30
0
def update_liveaction_status(
    status=None,
    result=None,
    context=None,
    end_timestamp=None,
    liveaction_id=None,
    runner_info=None,
    liveaction_db=None,
    publish=True,
):
    """
    Update the status of the specified LiveAction to the value provided in
    new_status.

    The LiveAction may be specified using either liveaction_id, or as an
    liveaction_db instance.
    """

    if (liveaction_id is None) and (liveaction_db is None):
        raise ValueError(
            "Must specify an liveaction_id or an liveaction_db when "
            "calling update_LiveAction_status"
        )

    if liveaction_db is None:
        liveaction_db = get_liveaction_by_id(liveaction_id)

    if status not in LIVEACTION_STATUSES:
        raise ValueError(
            'Attempting to set status for LiveAction "%s" '
            'to unknown status string. Unknown status is "%s"' % (liveaction_db, status)
        )

    if (
        result
        and cfg.CONF.system.validate_output_schema
        and status == LIVEACTION_STATUS_SUCCEEDED
    ):
        action_db = get_action_by_ref(liveaction_db.action)
        runner_db = get_runnertype_by_name(action_db.runner_type["name"])
        result, status = output_schema.validate_output(
            runner_db.output_schema,
            action_db.output_schema,
            result,
            status,
            runner_db.output_key,
        )

    # If liveaction_db status is set then we need to decrement the counter
    # because it is transitioning to a new state
    if liveaction_db.status:
        get_driver().dec_counter("action.executions.%s" % (liveaction_db.status))

    # If status is provided then we need to increment the timer because the action
    # is transitioning into this new state
    if status:
        get_driver().inc_counter("action.executions.%s" % (status))

    extra = {"liveaction_db": liveaction_db}
    LOG.debug(
        'Updating ActionExection: "%s" with status="%s"',
        liveaction_db.id,
        status,
        extra=extra,
    )

    # If liveaction is already canceled, then do not allow status to be updated.
    if (
        liveaction_db.status == LIVEACTION_STATUS_CANCELED
        and status != LIVEACTION_STATUS_CANCELED
    ):
        LOG.info(
            'Unable to update ActionExecution "%s" with status="%s". '
            "ActionExecution is already canceled.",
            liveaction_db.id,
            status,
            extra=extra,
        )
        return liveaction_db

    old_status = liveaction_db.status
    liveaction_db.status = status

    if result:
        liveaction_db.result = result

    if context:
        liveaction_db.context.update(context)

    if end_timestamp:
        liveaction_db.end_timestamp = end_timestamp

    if runner_info:
        liveaction_db.runner_info = runner_info

    # TODO: This is not efficient. Perform direct partial update and only update
    # manipulated fields
    liveaction_db = LiveAction.add_or_update(liveaction_db)

    LOG.debug("Updated status for LiveAction object.", extra=extra)

    if publish and status != old_status:
        LiveAction.publish_status(liveaction_db)
        LOG.debug("Published status for LiveAction object.", extra=extra)

    return liveaction_db
示例#31
0
def update_liveaction_status(status=None, result=None, context=None, end_timestamp=None,
                             liveaction_id=None, runner_info=None, liveaction_db=None,
                             publish=True):
    """
        Update the status of the specified LiveAction to the value provided in
        new_status.

        The LiveAction may be specified using either liveaction_id, or as an
        liveaction_db instance.
    """

    if (liveaction_id is None) and (liveaction_db is None):
        raise ValueError('Must specify an liveaction_id or an liveaction_db when '
                         'calling update_LiveAction_status')

    if liveaction_db is None:
        liveaction_db = get_liveaction_by_id(liveaction_id)

    if status not in LIVEACTION_STATUSES:
        raise ValueError('Attempting to set status for LiveAction "%s" '
                         'to unknown status string. Unknown status is "%s"',
                         liveaction_db, status)

    # If liveaction_db status is set then we need to decrement the counter
    # because it is transitioning to a new state
    if liveaction_db.status:
        get_driver().dec_counter('action.executions.%s' % (liveaction_db.status))

    # If status is provided then we need to increment the timer because the action
    # is transitioning into this new state
    if status:
        get_driver().inc_counter('action.executions.%s' % (status))

    extra = {'liveaction_db': liveaction_db}
    LOG.debug('Updating ActionExection: "%s" with status="%s"', liveaction_db.id, status,
              extra=extra)

    # If liveaction is already canceled, then do not allow status to be updated.
    if liveaction_db.status == LIVEACTION_STATUS_CANCELED and status != LIVEACTION_STATUS_CANCELED:
        LOG.info('Unable to update ActionExecution "%s" with status="%s". '
                 'ActionExecution is already canceled.', liveaction_db.id, status, extra=extra)
        return liveaction_db

    old_status = liveaction_db.status
    liveaction_db.status = status

    if result:
        liveaction_db.result = result

    if context:
        liveaction_db.context.update(context)

    if end_timestamp:
        liveaction_db.end_timestamp = end_timestamp

    if runner_info:
        liveaction_db.runner_info = runner_info

    liveaction_db = LiveAction.add_or_update(liveaction_db)

    LOG.debug('Updated status for LiveAction object.', extra=extra)

    if publish and status != old_status:
        LiveAction.publish_status(liveaction_db)
        LOG.debug('Published status for LiveAction object.', extra=extra)

    return liveaction_db