Exemple #1
0
def task_user_callback_cb(task_id, parent_task_id, cb, **kwargs):
    """
    Task for calling remote url in user defined callback
    """
    try:
        obj = get_task_object(kwargs)
    except ObjectDoesNotExist:
        obj = None

    user = User.objects.get(id=user_id_from_task_id(parent_task_id))
    payload, status = get_task_status(parent_task_id)

    try:
        response = UserCallback(parent_task_id).request(
            cb, user.callback_key, payload)
    except RequestException as ex:
        status = states.FAILURE
        details = ex
    else:
        status = states.SUCCESS
        details = str(response.status_code) + ': ' + response.reason

    if cb.get('cb_log'):
        task_log(parent_task_id,
                 LOG_REMOTE_CALLBACK,
                 obj=obj,
                 task_status=status,
                 detail=details)
Exemple #2
0
def task_log_cb(result,
                task_id,
                task_status=None,
                msg='',
                vm=None,
                obj=None,
                cleanup=False,
                check_returncode=False,
                **kwargs):
    """
    Log callback -> logs finished task.
    """
    if vm:
        obj = vm

    if not obj:
        try:
            obj = get_task_object(kwargs)
        except ObjectDoesNotExist:
            pass

    if cleanup:
        # Sometimes when an execute task fails with an exception or is revoked
        # we might need to run things that the callback would run. But now the
        # callback won't run so emergency cleanup should go into this function.
        try:
            logger.info('Running cleanup for task=%s with task_status=%s',
                        task_id, task_status)
            task_cleanup(result, task_id, task_status, obj, **kwargs)
        except Exception as e:
            logger.exception(e)
            logger.error(
                'Got exception (%s) when doing cleanup for task=%s, task_status=%s, obj=%s',
                e, task_id, task_status, obj)

    if check_returncode:
        rc = result.get('returncode', None)

        if rc != 0:
            err = 'Got bad return code (%s)' % rc
            err_msg = result.get('message', None)

            if err_msg:
                err += ' Error: %s' % err_msg

            logger.error(
                'Found nonzero returncode in result from %s. Error: %s',
                kwargs.get('apiview', msg), result)
            raise TaskException(result, err)

    task_log(task_id,
             msg,
             obj=obj,
             task_status=task_status,
             task_result=result)

    return result
Exemple #3
0
    def _update(cls, task_id, repo):
        err = res = images = None
        repo_url = repo.get_images_url()
        logger.info('Downloading images from image repository %s (%s)',
                    repo.name, repo_url)

        try:
            curl = HttpClient(repo_url)
            res = curl.get(timeout=cls.HTTP_TIMEOUT,
                           max_size=cls.HTTP_MAX_SIZE,
                           allow_redirects=True)
            images = res.json()
        except RequestException as exc:
            err = '%s' % exc
        except ValueError as exc:
            err = 'Image server response could not be decoded (%s)' % exc
        else:
            if not isinstance(images, list):
                err = 'Unexpected output from image server (%s)' % type(images)

        if err:
            status = FAILURE
            msg = err
            logger.error(err)
            repo.error = err
            repo.save()
        else:
            status = SUCCESS
            img_count = len(images)
            msg = u'Downloaded metadata for %d images from image repository %s in %d μs' % (
                img_count, repo.name, res.elapsed.microseconds)
            logger.info(msg)
            repo.image_count = img_count
            repo.last_update = timezone.now()
            repo.error = None
            repo.save(images=images)
            del images  # The list can be big => remove from memory, we don't need it now

        task_log(task_id,
                 LOG_IMAGE_STORE_UPDATE,
                 obj=repo,
                 task_status=status,
                 detail=msg,
                 update_user_tasks=False)

        return repo
Exemple #4
0
    def save(self, status):
        """Save task log entry if result is not None"""
        if hasattr(status, '__iter__'):
            status = [i for i in status if i is not None]  # remove None from result

            if status:
                success = all(status)
            else:
                success = None
        else:
            success = status

        if success is None:
            return

        if success:
            task_status = states.SUCCESS
        else:
            task_status = states.FAILURE

        task_log(self.task_id, self.msg, obj=self.obj, task_status=task_status, task_result=True,
                 detail=self.get_detail(), dc_id=self.dc_id, update_user_tasks=False)
Exemple #5
0
def vm_status_changed(tid,
                      vm,
                      state,
                      old_state=None,
                      save_state=True,
                      deploy_over=False,
                      change_time=None):
    """
    This function is something like a dummy callback.
    It should be called when VM state is changed from a task.
    """
    if change_time:
        old_change_time = cache.get(Vm.status_change_key(vm.uuid))

        if old_change_time and old_change_time > change_time:
            logger.warn(
                'Ignoring status change %s->%s of VM %s (%s) because it is too old: %s > %s',
                vm.status, state, vm, vm.uuid, old_change_time, change_time)
            return None

    # save to DB and also update cache
    if save_state:
        vm.status = state
        if old_state is not None:  # if cached status != vm.status (don't remember why we need this)
            vm._orig_status = old_state
        vm.save(update_fields=('status', 'status_change', 'uptime',
                               'uptime_changed'),
                status_change_time=change_time)

    if deploy_over:  # deploy process ended
        # Set the deploy_finished flag to inform vm_create_cb
        vm.set_deploy_finished()

    if vm.is_slave_vm():
        logger.info('Detected status change of slave VM %s - "%s"', vm.uuid,
                    vm)
        return None

    # Adjust task ID according to VM parameters
    tid = task_id_from_task_id(tid, owner_id=vm.owner.id, dc_id=vm.dc_id)

    # Signals!
    vm_status_changed_sig.send(tid,
                               vm=vm,
                               old_state=old_state,
                               new_state=state)  # Signal!
    if vm.status == vm.RUNNING:
        vm_running.send(tid, vm=vm, old_state=old_state)  # Signal!
    elif vm.status == vm.STOPPED:
        vm_stopped.send(tid, vm=vm, old_state=old_state)  # Signal!

    # data for next operations
    msg = LOG_STATUS_CHANGE
    task_event = VmStatusChanged(tid, vm)

    # log task
    task_log(tid,
             msg,
             vm=vm,
             owner=vm.owner,
             task_result=task_event.result,
             task_status=states.SUCCESS,
             time=vm.status_change,
             update_user_tasks=False)

    # inform users (VM owners logged in GUI)
    task_event.send()
Exemple #6
0
    def __init__(self,
                 request,
                 result,
                 task_id,
                 msg='',
                 vm=None,
                 obj=None,
                 owner=None,
                 api_view=None,
                 api_data=None,
                 detail='',
                 detail_dict=None,
                 callback=None,
                 **kwargs):

        if api_view is None:
            api_view = {}

        if api_data is None:
            api_data = {}

        if vm:
            obj = vm

        if task_id:  # Exceptions set the task_id to None
            task_pending = False

            # noinspection PyBroadException
            try:
                t_s = result['status']
            except Exception:
                t_s = None
            # noinspection PyBroadException
            try:
                t_r = result['result']
            except Exception:
                t_r = None

            if msg:  # msg => update task log & save pending user task
                if detail_dict:
                    detail = self.check_detail(detail)
                    detail += self.dict_to_detail(detail_dict)

                detail = self.save_callback(task_id, callback, detail=detail)
                task_pending = task_log(task_id,
                                        msg,
                                        obj=obj,
                                        user=request.user,
                                        api_view=api_view,
                                        owner=owner,
                                        task_status=t_s,
                                        task_result=t_r,
                                        detail=detail)

            elif t_s in TASK_STATE_PENDING and obj:  # => save pending user task
                task_pending = True
                self.save_callback(task_id, callback)

                try:
                    obj.tasks_add(task_id, api_view)
                except Exception as e:
                    logger.exception(e)
                    logger.error(
                        'Got exception (%s) when updating task %s for %s.', e,
                        task_id, obj)

            if task_pending:  # pending user task => send 'task-created' event
                context = request.parser_context
                # Send celery 'task-created' event, which may be captured by sio.monitor.que_monitor()
                # (this is a replacement for the internal 'task-sent' celery event)
                TaskCreatedEvent(task_id,
                                 apiview=api_view,
                                 task_status=t_s,
                                 task_result=t_r,
                                 method=request.method,
                                 view=context['view'].__class__.__name__,
                                 siosid=getattr(request, 'siosid', None),
                                 args=context['args'],
                                 kwargs=context['kwargs'],
                                 apidata=api_data).send()

        for i in UNUSED_RESPONSE_KWARGS:
            try:
                del kwargs[i]
            except KeyError:
                pass

        super(BaseTaskResponse, self).__init__(result,
                                               request=request,
                                               **kwargs)
        # Set es_task_id header
        self['es_task_id'] = task_id or ''
        # Attributes used by sio.namespaces.APINamespace
        self.apiview = api_view
        self.apidata = api_data