Commit 87987d11 authored by Christos Stavrakakis's avatar Christos Stavrakakis
Browse files

cyclades: Fix bugs relative with quotas

* Reject previous unaccepted serials if action is 'DESTROY'. This is
  required because multiple DESTROY actions may be pending for the same
  resource (e.g. VM). The one who succeeds will be accepted, while all
  others will be rejected. This isn't optimal since it causes circular
  issuing and rejection of commissions and should be fixed in a better
  way.
* Update dispatcher to handle commissions before updating the state of
  the VM, since if a new commission will be issued, this commission will
  depend on the state of the VM.
parent 9411bce4
......@@ -147,16 +147,20 @@ def process_op_status(vm, etime, jobid, opcode, status, logmsg, nics=None,
if job_fields is None:
job_fields = {}
new_operstate = None
state_for_success = VirtualMachine.OPER_STATE_FROM_OPCODE.get(opcode)
# Notifications of success change the operating state
if status == rapi.JOB_STATUS_SUCCESS:
# If job succeeds, change operating state if needed
if state_for_success is not None:
vm.operstate = state_for_success
new_operstate = state_for_success
beparams = job_fields.get("beparams", None)
if beparams:
# Change the flavor of the VM
_process_resize(vm, beparams)
# Update backendtime only for jobs that have been successfully
# completed, since only these jobs update the state of the VM. Else a
# "race condition" may occur when a successful job (e.g.
......@@ -171,7 +175,7 @@ def process_op_status(vm, etime, jobid, opcode, status, logmsg, nics=None,
# Special case: if OP_INSTANCE_CREATE fails --> ERROR
if opcode == 'OP_INSTANCE_CREATE' and status in (rapi.JOB_STATUS_CANCELED,
rapi.JOB_STATUS_ERROR):
vm.operstate = 'ERROR'
new_operstate = "ERROR"
vm.backendtime = etime
# Update state of associated NICs
vm.nics.all().update(state="ERROR")
......@@ -188,7 +192,7 @@ def process_op_status(vm, etime, jobid, opcode, status, logmsg, nics=None,
# And delete the NIC.
nic.delete()
vm.deleted = True
vm.operstate = state_for_success
new_operstate = state_for_success
vm.backendtime = etime
status = rapi.JOB_STATUS_SUCCESS
......@@ -201,6 +205,9 @@ def process_op_status(vm, etime, jobid, opcode, status, logmsg, nics=None,
vm.task = None
vm.task_job_id = None
if new_operstate is not None:
vm.operstate = new_operstate
vm.save()
......
......@@ -347,7 +347,12 @@ def handle_resource_commission(resource, action, commission_name,
resolved it before issuing the new one.
"""
# Try to resolve previous serial
# Try to resolve previous serial:
# If action is DESTROY, we must always reject the previous commission,
# since multiple DESTROY actions are allowed in the same resource (e.g. VM)
# The one who succeeds will be finally accepted, and all other will be
# rejected
force = force or (action == "DESTROY")
resolve_commission(resource.serial, force=force)
serial = issue_commission(resource, action, name=commission_name,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment