root / logic / backend.py @ ac63eb4f
History | View | Annotate | Download (4.2 kB)
1 | 234f8b07 | Vangelis Koukis | #
|
---|---|---|---|
2 | 234f8b07 | Vangelis Koukis | # Business Logic for communication with the Ganeti backend
|
3 | 234f8b07 | Vangelis Koukis | #
|
4 | 234f8b07 | Vangelis Koukis | # Copyright 2010 Greek Research and Technology Network
|
5 | 234f8b07 | Vangelis Koukis | #
|
6 | 02feca11 | Vassilios Karakoidas | |
7 | 529178b1 | Giorgos Verigakis | from django.conf import settings |
8 | 234f8b07 | Vangelis Koukis | from synnefo.db.models import VirtualMachine |
9 | 234f8b07 | Vangelis Koukis | from synnefo.logic import utils |
10 | 529178b1 | Giorgos Verigakis | from synnefo.util.rapi import GanetiRapiClient |
11 | 529178b1 | Giorgos Verigakis | |
12 | 529178b1 | Giorgos Verigakis | |
13 | 529178b1 | Giorgos Verigakis | rapi = GanetiRapiClient(*settings.GANETI_CLUSTER_INFO) |
14 | 529178b1 | Giorgos Verigakis | |
15 | 02feca11 | Vassilios Karakoidas | |
16 | ad2d6807 | Vangelis Koukis | def process_op_status(vm, jobid, opcode, status, logmsg): |
17 | ad2d6807 | Vangelis Koukis | """Process a job progress notification from the backend
|
18 | 02feca11 | Vassilios Karakoidas |
|
19 | 02feca11 | Vassilios Karakoidas | Process an incoming message from the backend (currently Ganeti).
|
20 | 02feca11 | Vassilios Karakoidas | Job notifications with a terminating status (sucess, error, or canceled),
|
21 | 02feca11 | Vassilios Karakoidas | also update the operating state of the VM.
|
22 | 02feca11 | Vassilios Karakoidas |
|
23 | 02feca11 | Vassilios Karakoidas | """
|
24 | 02feca11 | Vassilios Karakoidas | if (opcode not in [x[0] for x in VirtualMachine.BACKEND_OPCODES] or |
25 | 02feca11 | Vassilios Karakoidas | status not in [x[0] for x in VirtualMachine.BACKEND_STATUSES]): |
26 | 02feca11 | Vassilios Karakoidas | raise VirtualMachine.InvalidBackendMsgError(opcode, status)
|
27 | 02feca11 | Vassilios Karakoidas | |
28 | dfd19c2d | Vassilios Karakoidas | vm.backendjobid = jobid |
29 | dfd19c2d | Vassilios Karakoidas | vm.backendjobstatus = status |
30 | dfd19c2d | Vassilios Karakoidas | vm.backendopcode = opcode |
31 | dfd19c2d | Vassilios Karakoidas | vm.backendlogmsg = logmsg |
32 | 02feca11 | Vassilios Karakoidas | |
33 | 02feca11 | Vassilios Karakoidas | # Notifications of success change the operating state
|
34 | ac63eb4f | Vangelis Koukis | if status == 'success' and VirtualMachine.OPER_STATE_FROM_OPCODE[opcode] is not None: |
35 | 234f8b07 | Vangelis Koukis | utils.update_state(vm, VirtualMachine.OPER_STATE_FROM_OPCODE[opcode]) |
36 | 685b219e | Vangelis Koukis | # Set the deleted flag explicitly, to cater for admin-initiated removals
|
37 | 685b219e | Vangelis Koukis | if opcode == 'OP_INSTANCE_REMOVE': |
38 | 685b219e | Vangelis Koukis | vm.deleted = True
|
39 | 685b219e | Vangelis Koukis | |
40 | 685b219e | Vangelis Koukis | # Special case: if OP_INSTANCE_CREATE fails --> ERROR
|
41 | 02feca11 | Vassilios Karakoidas | if status in ('canceled', 'error') and opcode == 'OP_INSTANCE_CREATE': |
42 | 234f8b07 | Vangelis Koukis | utils.update_state(vm, 'ERROR')
|
43 | 02feca11 | Vassilios Karakoidas | # Any other notification of failure leaves the operating state unchanged
|
44 | 02feca11 | Vassilios Karakoidas | |
45 | 02feca11 | Vassilios Karakoidas | vm.save() |
46 | 22e52ede | Vassilios Karakoidas | |
47 | ad2d6807 | Vangelis Koukis | |
48 | ad2d6807 | Vangelis Koukis | def process_net_status(vm, nics): |
49 | ad2d6807 | Vangelis Koukis | """Process a net status notification from the backend
|
50 | ad2d6807 | Vangelis Koukis |
|
51 | ad2d6807 | Vangelis Koukis | Process an incoming message from the Ganeti backend,
|
52 | ad2d6807 | Vangelis Koukis | detailing the NIC configuration of a VM instance.
|
53 | ad2d6807 | Vangelis Koukis |
|
54 | ad2d6807 | Vangelis Koukis | Update the state of the VM in the DB accordingly.
|
55 | ad2d6807 | Vangelis Koukis |
|
56 | ad2d6807 | Vangelis Koukis | """
|
57 | ad2d6807 | Vangelis Koukis | |
58 | ad2d6807 | Vangelis Koukis | # For the time being, we can only update the ipfour field,
|
59 | ad2d6807 | Vangelis Koukis | # based on the IPv4 address of the first NIC
|
60 | 03805fc8 | Vangelis Koukis | if len(nics) > 0: |
61 | 03805fc8 | Vangelis Koukis | ipv4 = nics[0]['ip'] |
62 | 03805fc8 | Vangelis Koukis | if ipv4 == '': |
63 | 03805fc8 | Vangelis Koukis | ipv4 = '0.0.0.0'
|
64 | 03805fc8 | Vangelis Koukis | vm.ipfour = ipv4 |
65 | ad2d6807 | Vangelis Koukis | vm.save() |
66 | ad2d6807 | Vangelis Koukis | |
67 | ad2d6807 | Vangelis Koukis | |
68 | 22e52ede | Vassilios Karakoidas | def start_action(vm, action): |
69 | 22e52ede | Vassilios Karakoidas | """Update the state of a VM when a new action is initiated."""
|
70 | 22e52ede | Vassilios Karakoidas | if not action in [x[0] for x in VirtualMachine.ACTIONS]: |
71 | 22e52ede | Vassilios Karakoidas | raise VirtualMachine.InvalidActionError(action)
|
72 | 22e52ede | Vassilios Karakoidas | |
73 | 22e52ede | Vassilios Karakoidas | # No actions to deleted and no actions beside destroy to suspended VMs
|
74 | 22e52ede | Vassilios Karakoidas | if vm.deleted:
|
75 | 5231a38a | Giorgos Verigakis | raise VirtualMachine.DeletedError
|
76 | 30f3b5e5 | Vangelis Koukis | |
77 | 30f3b5e5 | Vangelis Koukis | # No actions to machines being built. They may be destroyed, however.
|
78 | 30f3b5e5 | Vangelis Koukis | if vm.operstate == 'BUILD' and action != 'DESTROY': |
79 | 5231a38a | Giorgos Verigakis | raise VirtualMachine.BuildingError
|
80 | 5231a38a | Giorgos Verigakis | |
81 | dfd19c2d | Vassilios Karakoidas | vm.action = action |
82 | dfd19c2d | Vassilios Karakoidas | vm.backendjobid = None
|
83 | dfd19c2d | Vassilios Karakoidas | vm.backendopcode = None
|
84 | dfd19c2d | Vassilios Karakoidas | vm.backendjobstatus = None
|
85 | dfd19c2d | Vassilios Karakoidas | vm.backendlogmsg = None
|
86 | 22e52ede | Vassilios Karakoidas | |
87 | 22e52ede | Vassilios Karakoidas | # Update the relevant flags if the VM is being suspended or destroyed
|
88 | 22e52ede | Vassilios Karakoidas | if action == "DESTROY": |
89 | 22e52ede | Vassilios Karakoidas | vm.deleted = True
|
90 | 22e52ede | Vassilios Karakoidas | elif action == "SUSPEND": |
91 | 22e52ede | Vassilios Karakoidas | vm.suspended = True
|
92 | 22e52ede | Vassilios Karakoidas | elif action == "START": |
93 | 22e52ede | Vassilios Karakoidas | vm.suspended = False
|
94 | 22e52ede | Vassilios Karakoidas | vm.save() |
95 | 529178b1 | Giorgos Verigakis | |
96 | ad2d6807 | Vangelis Koukis | |
97 | 529178b1 | Giorgos Verigakis | def create_instance(vm, flavor, password): |
98 | 529178b1 | Giorgos Verigakis | # FIXME: `password` must be passed to the Ganeti OS provider via CreateInstance()
|
99 | 529178b1 | Giorgos Verigakis | return rapi.CreateInstance(
|
100 | 529178b1 | Giorgos Verigakis | mode='create',
|
101 | 12fd6446 | Giorgos Verigakis | name=vm.backend_id, |
102 | 529178b1 | Giorgos Verigakis | disk_template='plain',
|
103 | 529178b1 | Giorgos Verigakis | disks=[{"size": 2000}], #FIXME: Always ask for a 2GB disk for now |
104 | 529178b1 | Giorgos Verigakis | nics=[{}], |
105 | 529178b1 | Giorgos Verigakis | os='debootstrap+default', #TODO: select OS from imageRef |
106 | 529178b1 | Giorgos Verigakis | ip_check=False,
|
107 | 529178b1 | Giorgos Verigakis | name_check=False,
|
108 | 529178b1 | Giorgos Verigakis | pnode=rapi.GetNodes()[0], #TODO: verify if this is necessary |
109 | 529178b1 | Giorgos Verigakis | dry_run=settings.TEST, |
110 | 529178b1 | Giorgos Verigakis | beparams=dict(auto_balance=True, vcpus=flavor.cpu, memory=flavor.ram)) |
111 | 529178b1 | Giorgos Verigakis | |
112 | 529178b1 | Giorgos Verigakis | def delete_instance(vm): |
113 | 529178b1 | Giorgos Verigakis | start_action(vm, 'DESTROY')
|
114 | 529178b1 | Giorgos Verigakis | rapi.DeleteInstance(vm.backend_id) |
115 | 529178b1 | Giorgos Verigakis | |
116 | ad2d6807 | Vangelis Koukis | |
117 | 529178b1 | Giorgos Verigakis | def reboot_instance(vm, reboot_type): |
118 | 529178b1 | Giorgos Verigakis | assert reboot_type in ('soft', 'hard') |
119 | 529178b1 | Giorgos Verigakis | rapi.RebootInstance(vm.backend_id, reboot_type) |
120 | 529178b1 | Giorgos Verigakis | |
121 | ad2d6807 | Vangelis Koukis | |
122 | 529178b1 | Giorgos Verigakis | def startup_instance(vm): |
123 | 529178b1 | Giorgos Verigakis | start_action(vm, 'START')
|
124 | 529178b1 | Giorgos Verigakis | rapi.StartupInstance(vm.backend_id) |
125 | 529178b1 | Giorgos Verigakis | |
126 | ad2d6807 | Vangelis Koukis | |
127 | 529178b1 | Giorgos Verigakis | def shutdown_instance(vm): |
128 | 529178b1 | Giorgos Verigakis | start_action(vm, 'STOP')
|
129 | 529178b1 | Giorgos Verigakis | rapi.ShutdownInstance(vm.backend_id) |
130 | 529178b1 | Giorgos Verigakis | |
131 | ad2d6807 | Vangelis Koukis | |
132 | 529178b1 | Giorgos Verigakis | def get_instance_console(vm): |
133 | 529178b1 | Giorgos Verigakis | return rapi.GetInstanceConsole(vm.backend_id) |