Beispiel #1
0
    def _task_status(self, task_id, event_status, tt):
        if tt == TT_MGMT and task_id not in self.last_tasks:
            self.log('Ignoring mgmt task %s, because we never called it', task_id, level=DEBUG)
            return

        task = cq.AsyncResult(task_id)

        if get_callback(task):
            self.log('Ignoring task %s, because it has a callback', task_id, level=DEBUG)
            return

        parent_task_id = is_callback(task)

        if parent_task_id:
            _task_id = task_id
            task_id = parent_task_id
            self.log('Changing task %s to %s, because it is a callback', _task_id, task_id, level=DEBUG)
        elif is_logtask(task):
            self.log('Ignoring task %s, because it is a logtask without caller', task_id)
            return

        # Try to get the apiview information from cache
        apiview = None
        # noinspection PyBroadException
        try:
            apiview = cache.get('sio-' + task_id)
        except Exception:
            pass
        if not apiview:
            apiview = {}

        res = self._api_task_status(task_id)
        self.log('Task %s %s', task_id, event_status)
        self.emit('task_status', res.data, apiview)
Beispiel #2
0
def task_log(task_id,
             msg,
             vm=None,
             obj=None,
             user=None,
             api_view=None,
             task_status=None,
             task_result=None,
             owner=None,
             time=None,
             detail=None,
             update_user_tasks=True,
             dc_id=None,
             **kwargs):
    """
    Create task log read by the user. Also maintain dictionary of active tasks for specific VM.
    """
    task_id = str(task_id)
    task_prefix = task_prefix_from_task_id(task_id)
    dc_id = dc_id or int(
        task_prefix[4])  # Specifying a custom dc_id is usually not a good idea
    update_tasks = False

    # When? (time)
    if not time:
        time = timezone.now()

    # Who? (username, task creator)
    if user and not isinstance(user, string_types):
        username = user.username
        user_id = user.id
    else:
        user = None
        user_id = int(task_prefix[0])
        if user_id == int(cq.conf.ERIGONES_TASK_USER):
            username = cq.conf.ERIGONES_TASK_USERNAME
        else:
            try:
                username = User.objects.get(id=user_id).username
            except User.DoesNotExist:
                username = '******'

    # What? (status and result)
    if not task_status or not task_result:
        # Do not follow callback here, because we are called from pending callbacks
        task = cq.AsyncResult(task_id)
        if not task_status:
            task_status = task.state
        if not task_result:
            task_result = task.result

    # Object? (Vm, Node, ...)
    if vm:
        obj = vm

    if obj and isinstance(obj, (tuple, list)):
        object_name = obj[0]
        object_alias = obj[1]
        object_pk = obj[2]
        content_type = ContentType.objects.get_for_model(obj[3])
        object_type = content_type.model
        obj = None
    elif obj and not isinstance(obj, string_types):
        object_name = obj.log_name
        object_alias = obj.log_alias
        object_pk = obj.pk
        content_type = ContentType.objects.get_for_model(obj)
        object_type = content_type.model

        if update_user_tasks and hasattr(obj, 'tasks'):
            update_tasks = True

    else:
        if obj:
            object_name = str(obj)
        else:
            object_name = ''

        object_alias = ''
        object_pk = ''
        obj = None
        content_type = None
        object_type = None

    if object_pk is None:
        object_pk = ''
    else:
        object_pk = str(object_pk)

    # Detail?
    if not detail:
        if task_result:
            # noinspection PyBroadException
            try:
                detail = task_result['detail']
            except:
                # noinspection PyBroadException
                try:
                    detail = task_result['message']
                except:
                    detail = ''
        if detail is None:
            detail = ''

    # Owner?
    if not owner:
        if obj:
            # noinspection PyBroadException
            try:
                owner = obj.owner
            except:
                owner = user
        elif user:
            owner = user

    # noinspection PyBroadException
    try:
        owner_id = owner.id
    except:
        owner_id = int(task_prefix[2])

    if task_status == states.STARTED:
        task_status = states.PENDING

    try:  # Log!
        log({
            'dc_id': dc_id,
            'time': time,
            'task': task_id,
            'status': task_status,
            'task_type': task_type_from_task_prefix(task_prefix),
            'flag': task_flag_from_task_msg(msg),
            'user_id': user_id,
            'username': username,
            'owner_id': owner_id,
            'object_pk': object_pk,
            'object_type': object_type,
            'object_name': object_name,
            'object_alias': object_alias,
            'content_type': content_type,
            'msg': msg,
            'detail': detail,
        })
    finally:
        if update_tasks:  # Save task info into UserTasks cache after the task was logged
            try:
                if task_status in TASK_STATE_PENDING:
                    obj.tasks_add(task_id,
                                  api_view,
                                  msg=msg,
                                  time=time.isoformat())

                    return True
                else:
                    obj.tasks_del(task_id)
            except Exception as e:
                logger.exception(e)
                logger.error(
                    'Got exception (%s) when updating task %s for %s.', e,
                    task_id, obj)

    return None
Beispiel #3
0
        def inner(task_obj, result, task_id, *args, **kwargs):
            try:  # Just in case, there will be probably no callback information at this point
                del result['meta']['callback']
            except KeyError:
                pass

            result['meta']['caller'] = task_id

            if meta_kwargs:
                result['meta'].update(meta_kwargs)

            # Issue #chili-512
            # + skipping checking of parent task status when task is being retried
            if check_parent_status and not task_obj.request.retries:
                cb_name = fun.__name__
                logger.debug(
                    'Waiting for parent task %s status, before running %s',
                    task_id, cb_name)
                timer = 0

                while timer < TASK_PARENT_STATUS_MAXWAIT:
                    ar = cq.AsyncResult(task_id)
                    if ar.ready():
                        logger.info(
                            'Parent task %s has finished with status=%s. Running %s',
                            task_id, ar.status, cb_name)
                        break

                    timer += 1
                    logger.warning(
                        'Whoa! Parent task %s has not finished yet with status=%s. Waiting 1 second (%d), '
                        'before running %s', task_id, ar.status, timer,
                        cb_name)
                    sleep(1.0)
                else:
                    logger.error('Task %s is not ready. Running %s anyway :(',
                                 task_id, cb_name)

            try:
                return fun(result, task_id, *args, **kwargs)
            except OPERATIONAL_ERRORS as exc:
                raise exc  # Caught by que.mgmt.MgmtCallbackTask
            except Exception as e:
                logger.exception(e)
                logger.error('Task %s failed', task_id)

                if not isinstance(e, TaskException):
                    e = TaskException(result, str(e))

                if log_exception or update_user_tasks:
                    if e.obj is None:
                        try:
                            obj = get_vms_object(kwargs)
                        except ObjectDoesNotExist:
                            obj = None
                            # noinspection PyProtectedMember
                            _UserTasksModel._tasks_del(
                                task_id)  # Always remove user task
                    else:
                        obj = e.obj

                    if log_exception:
                        msg = e.result['meta'].get('msg', '')
                        # Also removes user task in task_log
                        task_log(task_id,
                                 msg,
                                 obj=obj,
                                 task_status=states.FAILURE,
                                 task_result=e.result)
                    elif obj:  # update_user_tasks
                        obj.tasks_del(task_id)

                if error_fun:
                    try:
                        error_fun(result,
                                  task_id,
                                  task_exception=e,
                                  *args,
                                  **kwargs)
                    except Exception as ex:
                        logger.exception(ex)

                raise e

            finally:
                cb = UserCallback(task_id).load()

                if cb:
                    logger.debug('Creating task for UserCallback[%s]: %s',
                                 task_id, cb)
                    from api.task.tasks import task_user_callback_cb  # Circular import
                    task_user_callback_cb.call(task_id, cb, **kwargs)