Beispiel #1
0
def handle_vm_quotas(vm, job_id, job_opcode, job_status, job_fields):
    """Handle quotas for updated VirtualMachine.

    Update quotas for the updated VirtualMachine based on the job that run on
    the Ganeti backend. If a commission has been already issued for this job,
    then this commission is just accepted or rejected based on the job status.
    Otherwise, a new commission for the given change is issued, that is also in
    force and auto-accept mode. In this case, previous commissions are
    rejected, since they reflect a previous state of the VM.

    """
    if job_status not in rapi.JOB_STATUS_FINALIZED:
        return vm
    print vm
    print vm

    # Check successful completion of a job will trigger any quotable change in
    # the VM state.
    action = utils.get_action_from_opcode(job_opcode, job_fields)
    if action == "BUILD":
        # Quotas for new VMs are automatically accepted by the API
        return vm

    if vm.task_job_id == job_id and vm.serial is not None:
        # Commission for this change has already been issued. So just
        # accept/reject it. Special case is OP_INSTANCE_CREATE, which even
        # if fails, must be accepted, as the user must manually remove the
        # failed server
        serial = vm.serial
        if job_status == rapi.JOB_STATUS_SUCCESS:
            quotas.accept_resource_serial(vm)
        elif job_status in [rapi.JOB_STATUS_ERROR, rapi.JOB_STATUS_CANCELED]:
            log.debug("Job %s failed. Rejecting related serial %s", job_id,
                      serial)
            quotas.reject_resource_serial(vm)
    elif job_status == rapi.JOB_STATUS_SUCCESS:
        commission_info = quotas.get_commission_info(resource=vm,
                                                     action=action,
                                                     action_fields=job_fields)
        if commission_info is not None:
            # Commission for this change has not been issued, or the issued
            # commission was unaware of the current change. Reject all previous
            # commissions and create a new one in forced mode!
            log.debug("Expected job was %s. Processing job %s. "
                      "Attached serial %s",
                      vm.task_job_id, job_id, vm.serial)
            reason = ("client: dispatcher, resource: %s, ganeti_job: %s"
                      % (vm, job_id))
            serial = quotas.handle_resource_commission(
                vm, action,
                action_fields=job_fields,
                commission_name=reason,
                force=True,
                auto_accept=True)
            log.debug("Issued new commission: %s", serial)
    return vm
Beispiel #2
0
def handle_vm_quotas(vm, job_id, job_opcode, job_status, job_fields):
    """Handle quotas for updated VirtualMachine.

    Update quotas for the updated VirtualMachine based on the job that run on
    the Ganeti backend. If a commission has been already issued for this job,
    then this commission is just accepted or rejected based on the job status.
    Otherwise, a new commission for the given change is issued, that is also in
    force and auto-accept mode. In this case, previous commissions are
    rejected, since they reflect a previous state of the VM.

    """
    if job_status not in rapi.JOB_STATUS_FINALIZED:
        return vm

    # Check successful completion of a job will trigger any quotable change in
    # the VM state.
    action = utils.get_action_from_opcode(job_opcode, job_fields)
    if action == "BUILD":
        # Quotas for new VMs are automatically accepted by the API
        return vm

    if vm.task_job_id == job_id and vm.serial is not None:
        # Commission for this change has already been issued. So just
        # accept/reject it. Special case is OP_INSTANCE_CREATE, which even
        # if fails, must be accepted, as the user must manually remove the
        # failed server
        serial = vm.serial
        if job_status == rapi.JOB_STATUS_SUCCESS:
            quotas.accept_resource_serial(vm)
        elif job_status in [rapi.JOB_STATUS_ERROR, rapi.JOB_STATUS_CANCELED]:
            log.debug("Job %s failed. Rejecting related serial %s", job_id,
                      serial)
            quotas.reject_resource_serial(vm)
    elif job_status == rapi.JOB_STATUS_SUCCESS:
        commission_info = quotas.get_commission_info(resource=vm,
                                                     action=action,
                                                     action_fields=job_fields)
        if commission_info is not None:
            # Commission for this change has not been issued, or the issued
            # commission was unaware of the current change. Reject all previous
            # commissions and create a new one in forced mode!
            log.debug(
                "Expected job was %s. Processing job %s. "
                "Attached serial %s", vm.task_job_id, job_id, vm.serial)
            reason = ("client: dispatcher, resource: %s, ganeti_job: %s" %
                      (vm, job_id))
            serial = quotas.handle_resource_commission(
                vm,
                action,
                action_fields=job_fields,
                commission_name=reason,
                force=True,
                auto_accept=True)
            log.debug("Issued new commission: %s", serial)
    return vm
Beispiel #3
0
        def wrapper(vm, *args, **kwargs):
            user_id = vm.userid
            validate_server_action(vm, action)
            vm.action = action

            commission_name = "client: api, resource: %s" % vm
            quotas.handle_resource_commission(vm,
                                              action=action,
                                              action_fields=action_fields,
                                              commission_name=commission_name)
            vm.save()

            # XXX: Special case for server creation!
            if action == "BUILD":
                # Perform a commit, because the VirtualMachine must be saved to
                # DB before the OP_INSTANCE_CREATE job in enqueued in Ganeti.
                # Otherwise, messages will arrive from snf-dispatcher about
                # this instance, before the VM is stored in DB.
                transaction.commit()
                # After committing the locks are released. Refetch the instance
                # to guarantee x-lock.
                vm = VirtualMachine.objects.select_for_update().get(id=vm.id)

            # Send the job to Ganeti and get the associated jobID
            try:
                job_id = func(vm, *args, **kwargs)
            except Exception as e:
                if vm.serial is not None:
                    # Since the job never reached Ganeti, reject the commission
                    log.debug("Rejecting commission: '%s', could not perform"
                              " action '%s': %s" % (vm.serial, action, e))
                    transaction.rollback()
                    quotas.reject_resource_serial(vm)
                    transaction.commit()
                raise

            if action == "BUILD" and vm.serial is not None:
                # XXX: Special case for server creation: we must accept the
                # commission because the VM has been stored in DB. Also, if
                # communication with Ganeti fails, the job will never reach
                # Ganeti, and the commission will never be resolved.
                quotas.accept_resource_serial(vm)

            log.info("user: %s, vm: %s, action: %s, job_id: %s, serial: %s",
                     user_id, vm.id, action, job_id, vm.serial)

            # store the new task in the VM
            if job_id is not None:
                vm.task = action
                vm.task_job_id = job_id
            vm.save()

            return vm
Beispiel #4
0
        def wrapper(vm, *args, **kwargs):
            user_id = vm.userid
            validate_server_action(vm, action)
            vm.action = action

            commission_name = "client: api, resource: %s" % vm
            quotas.handle_resource_commission(vm, action=action,
                                              action_fields=action_fields,
                                              commission_name=commission_name)
            vm.save()

            # XXX: Special case for server creation!
            if action == "BUILD":
                # Perform a commit, because the VirtualMachine must be saved to
                # DB before the OP_INSTANCE_CREATE job in enqueued in Ganeti.
                # Otherwise, messages will arrive from snf-dispatcher about
                # this instance, before the VM is stored in DB.
                transaction.commit()
                # After committing the locks are released. Refetch the instance
                # to guarantee x-lock.
                vm = VirtualMachine.objects.select_for_update().get(id=vm.id)

            # Send the job to Ganeti and get the associated jobID
            try:
                job_id = func(vm, *args, **kwargs)
            except Exception as e:
                if vm.serial is not None:
                    # Since the job never reached Ganeti, reject the commission
                    log.debug("Rejecting commission: '%s', could not perform"
                              " action '%s': %s" % (vm.serial,  action, e))
                    transaction.rollback()
                    quotas.reject_resource_serial(vm)
                    transaction.commit()
                raise

            if action == "BUILD" and vm.serial is not None:
                # XXX: Special case for server creation: we must accept the
                # commission because the VM has been stored in DB. Also, if
                # communication with Ganeti fails, the job will never reach
                # Ganeti, and the commission will never be resolved.
                quotas.accept_resource_serial(vm)

            log.info("user: %s, vm: %s, action: %s, job_id: %s, serial: %s",
                     user_id, vm.id, action, job_id, vm.serial)

            # store the new task in the VM
            if job_id is not None:
                vm.task = action
                vm.task_job_id = job_id
            vm.save()

            return vm