Revision 02feca11
b/db/db_controller.py | ||
---|---|---|
30 | 30 |
from threading import Thread, Event, currentThread |
31 | 31 |
|
32 | 32 |
from synnefo.db.models import VirtualMachine |
33 |
from synnefo.logic import utils |
|
33 |
|
|
34 |
from synnefo.logic import utils, backend |
|
34 | 35 |
|
35 | 36 |
GANETI_ZMQ_PUBLISHER = "tcp://62.217.120.67:5801" # FIXME: move to settings.py |
36 | 37 |
|
... | ... | |
73 | 74 |
vm = VirtualMachine.objects.get(id=vmid) |
74 | 75 |
|
75 | 76 |
logging.debug("Processing msg: %s" % (msg,)) |
76 |
vm.process_backend_msg(msg["jobId"], msg["operation"], msg["status"], msg["logmsg"])
|
|
77 |
backend.process_backend_msg(msg["jobId"], msg["operation"], msg["status"], msg["logmsg"])
|
|
77 | 78 |
vm.save() |
78 | 79 |
logging.debug("Done processing msg for vm %s." % (msg["instance"])) |
79 | 80 |
|
b/db/models.py | ||
---|---|---|
5 | 5 |
|
6 | 6 |
import datetime |
7 | 7 |
|
8 |
from logic import utils, credits |
|
8 | 9 |
|
9 | 10 |
class SynnefoUser(models.Model): |
10 | 11 |
name = models.CharField('Synnefo Username', max_length=255) |
... | ... | |
344 | 345 |
# breaking VirtualMachine.object.create() among other things. |
345 | 346 |
self._operstate = 'BUILD' |
346 | 347 |
|
347 |
def process_backend_msg(self, jobid, opcode, status, logmsg): |
|
348 |
"""Process a job progress notification from the backend. |
|
349 |
|
|
350 |
Process an incoming message from the backend (currently Ganeti). |
|
351 |
Job notifications with a terminating status (sucess, error, or canceled), |
|
352 |
also update the operating state of the VM. |
|
353 |
|
|
354 |
""" |
|
355 |
if (opcode not in [x[0] for x in VirtualMachine.BACKEND_OPCODES] or |
|
356 |
status not in [x[0] for x in VirtualMachine.BACKEND_STATUSES]): |
|
357 |
raise VirtualMachine.InvalidBackendMsgError(opcode, status) |
|
358 |
|
|
359 |
self._backendjobid = jobid |
|
360 |
self._backendjobstatus = status |
|
361 |
self._backendopcode = opcode |
|
362 |
self._backendlogmsg = logmsg |
|
363 |
|
|
364 |
# Notifications of success change the operating state |
|
365 |
if status == 'success': |
|
366 |
self._update_state(VirtualMachine.OPER_STATE_FROM_OPCODE[opcode]) |
|
367 |
# Special cases OP_INSTANCE_CREATE fails --> ERROR |
|
368 |
if status in ('canceled', 'error') and opcode == 'OP_INSTANCE_CREATE': |
|
369 |
self._update_state('ERROR') |
|
370 |
# Any other notification of failure leaves the operating state unchanged |
|
371 |
|
|
372 |
self.save() |
|
373 |
|
|
374 | 348 |
def start_action(self, action): |
375 | 349 |
"""Update the state of a VM when a new action is initiated.""" |
376 | 350 |
if not action in [x[0] for x in VirtualMachine.ACTIONS]: |
... | ... | |
395 | 369 |
self.suspended = False |
396 | 370 |
self.save() |
397 | 371 |
|
398 |
# FIXME: Perhaps move somewhere else, outside the model?
|
|
372 |
# FIXME: leave this here to preserve the property rsapistate
|
|
399 | 373 |
def _get_rsapi_state(self): |
400 |
try: |
|
401 |
r = VirtualMachine.RSAPI_STATE_FROM_OPER_STATE[self._operstate] |
|
402 |
except KeyError: |
|
403 |
return "UNKNOWN" |
|
404 |
# A machine is in REBOOT if an OP_INSTANCE_REBOOT request is in progress |
|
405 |
if r == 'ACTIVE' and self._backendopcode == 'OP_INSTANCE_REBOOT' and \ |
|
406 |
self._backendjobstatus in ('queued', 'waiting', 'running'): |
|
407 |
return "REBOOT" |
|
408 |
return r |
|
374 |
return utils.get_rsapi_state(self) |
|
409 | 375 |
|
410 | 376 |
rsapi_state = property(_get_rsapi_state) |
411 | 377 |
|
... | ... | |
431 | 397 |
|
432 | 398 |
# Call charge() unconditionally before any change of |
433 | 399 |
# internal state. |
434 |
self.charge()
|
|
400 |
credits.charge()
|
|
435 | 401 |
self._operstate = new_operstate |
436 | 402 |
|
437 | 403 |
|
b/logic/backend.py | ||
---|---|---|
1 |
|
|
2 |
from db.models import VirtualMachine |
|
3 |
|
|
4 |
def process_backend_msg(vm, jobid, opcode, status, logmsg): |
|
5 |
"""Process a job progress notification from the backend. |
|
6 |
|
|
7 |
Process an incoming message from the backend (currently Ganeti). |
|
8 |
Job notifications with a terminating status (sucess, error, or canceled), |
|
9 |
also update the operating state of the VM. |
|
10 |
|
|
11 |
""" |
|
12 |
if (opcode not in [x[0] for x in VirtualMachine.BACKEND_OPCODES] or |
|
13 |
status not in [x[0] for x in VirtualMachine.BACKEND_STATUSES]): |
|
14 |
raise VirtualMachine.InvalidBackendMsgError(opcode, status) |
|
15 |
|
|
16 |
vm._backendjobid = jobid |
|
17 |
vm._backendjobstatus = status |
|
18 |
vm._backendopcode = opcode |
|
19 |
vm._backendlogmsg = logmsg |
|
20 |
|
|
21 |
# Notifications of success change the operating state |
|
22 |
if status == 'success': |
|
23 |
vm._update_state(VirtualMachine.OPER_STATE_FROM_OPCODE[opcode]) |
|
24 |
# Special cases OP_INSTANCE_CREATE fails --> ERROR |
|
25 |
if status in ('canceled', 'error') and opcode == 'OP_INSTANCE_CREATE': |
|
26 |
vm._update_state('ERROR') |
|
27 |
# Any other notification of failure leaves the operating state unchanged |
|
28 |
|
|
29 |
vm.save() |
b/logic/utils.py | ||
---|---|---|
20 | 20 |
raise VirtualMachine.InvalidBackendIdError(str(name)) |
21 | 21 |
|
22 | 22 |
return int(ns) |
23 |
|
|
24 |
|
|
25 |
def get_rsapi_state(vm): |
|
26 |
"""Returns the RSAPI state for a virtual machine""" |
|
27 |
try: |
|
28 |
r = VirtualMachine.RSAPI_STATE_FROM_OPER_STATE[vm._operstate] |
|
29 |
except KeyError: |
|
30 |
return "UNKNOWN" |
|
31 |
# A machine is in REBOOT if an OP_INSTANCE_REBOOT request is in progress |
|
32 |
if r == 'ACTIVE' and vm._backendopcode == 'OP_INSTANCE_REBOOT' and \ |
|
33 |
vm._backendjobstatus in ('queued', 'waiting', 'running'): |
|
34 |
return "REBOOT" |
|
35 |
return r |
Also available in: Unified diff