Revision f533f224 logic/backend.py
b/logic/backend.py | ||
---|---|---|
5 | 5 |
# |
6 | 6 |
|
7 | 7 |
from django.conf import settings |
8 |
from synnefo.db.models import VirtualMachine |
|
8 |
from django.db import transaction |
|
9 |
|
|
10 |
from synnefo.db.models import VirtualMachine, Network, NetworkLink |
|
9 | 11 |
from synnefo.logic import utils |
10 | 12 |
from synnefo.util.rapi import GanetiRapiClient |
11 | 13 |
|
... | ... | |
45 | 47 |
vm.save() |
46 | 48 |
|
47 | 49 |
|
50 |
@transaction.commit_on_success |
|
48 | 51 |
def process_net_status(vm, nics): |
49 | 52 |
"""Process a net status notification from the backend |
50 | 53 |
|
... | ... | |
52 | 55 |
detailing the NIC configuration of a VM instance. |
53 | 56 |
|
54 | 57 |
Update the state of the VM in the DB accordingly. |
55 |
|
|
56 | 58 |
""" |
57 |
|
|
58 |
# For the time being, we can only update the ipfour field, |
|
59 |
# based on the IPv4 address of the first NIC |
|
60 |
if len(nics) > 0: |
|
61 |
ipv4 = nics[0]['ip'] |
|
62 |
if ipv4 == '': |
|
63 |
ipv4 = '0.0.0.0' |
|
64 |
vm.ipfour = ipv4 |
|
59 |
|
|
60 |
vm.nics.all().delete() |
|
61 |
for i, nic in enumerate(nics): |
|
62 |
if i == 0: |
|
63 |
net = Network.objects.get(public=True) |
|
64 |
else: |
|
65 |
try: |
|
66 |
link = NetworkLink.objects.get(name=nic['link']) |
|
67 |
except NetworkLink.DoesNotExist: |
|
68 |
# Cannot find an instance of NetworkLink for |
|
69 |
# the link attribute specified in the notification |
|
70 |
raise NetworkLink.DoesNotExist("Cannot find a NetworkLink " |
|
71 |
"object for link='%s'" % nic['link']) |
|
72 |
net = link.network |
|
73 |
if net is None: |
|
74 |
raise Network.DoesNotExist("NetworkLink for link='%s' not " |
|
75 |
"associated with an existing Network instance." % |
|
76 |
nic['link']) |
|
77 |
|
|
78 |
vm.nics.create( |
|
79 |
network=net, |
|
80 |
index=i, |
|
81 |
mac=nic.get('mac', ''), |
|
82 |
ipv4=nic.get('ip', '')) |
|
65 | 83 |
vm.save() |
66 | 84 |
|
67 | 85 |
|
... | ... | |
95 | 113 |
|
96 | 114 |
|
97 | 115 |
def create_instance(vm, flavor, image, password): |
116 |
|
|
117 |
nic = {'ip': 'pool', 'mode': 'routed', 'link': settings.GANETI_PUBLIC_LINK} |
|
118 |
|
|
98 | 119 |
return rapi.CreateInstance( |
99 | 120 |
mode='create', |
100 | 121 |
name=vm.backend_id, |
101 | 122 |
disk_template='plain', |
102 |
disks=[{"size": 4000}], #FIXME: Always ask for a 4GB disk for now
|
|
103 |
nics=[{}],
|
|
123 |
disks=[{"size": 4000}], #FIXME: Always ask for a 4GB disk for now |
|
124 |
nics=[nic],
|
|
104 | 125 |
os='image+default', |
105 | 126 |
ip_check=False, |
106 | 127 |
name_check=False, |
107 |
pnode=rapi.GetNodes()[0], #TODO: verify if this is necessary
|
|
128 |
pnode=rapi.GetNodes()[0], #TODO: use a Ganeti iallocator instead
|
|
108 | 129 |
dry_run=settings.TEST, |
109 | 130 |
beparams=dict(auto_balance=True, vcpus=flavor.cpu, memory=flavor.ram), |
110 |
osparams=dict(img_id=image.backend_id, img_passwd=password, img_format=image.format)) |
|
131 |
osparams=dict(img_id=image.backend_id, img_passwd=password, |
|
132 |
img_format=image.format)) |
|
133 |
|
|
111 | 134 |
|
112 | 135 |
def delete_instance(vm): |
113 | 136 |
start_action(vm, 'DESTROY') |
114 |
rapi.DeleteInstance(vm.backend_id) |
|
137 |
rapi.DeleteInstance(vm.backend_id, dry_run=settings.TEST) |
|
138 |
vm.nics.all().delete() |
|
115 | 139 |
|
116 | 140 |
|
117 | 141 |
def reboot_instance(vm, reboot_type): |
118 | 142 |
assert reboot_type in ('soft', 'hard') |
119 |
rapi.RebootInstance(vm.backend_id, reboot_type) |
|
143 |
rapi.RebootInstance(vm.backend_id, reboot_type, dry_run=settings.TEST)
|
|
120 | 144 |
|
121 | 145 |
|
122 | 146 |
def startup_instance(vm): |
123 | 147 |
start_action(vm, 'START') |
124 |
rapi.StartupInstance(vm.backend_id) |
|
148 |
rapi.StartupInstance(vm.backend_id, dry_run=settings.TEST)
|
|
125 | 149 |
|
126 | 150 |
|
127 | 151 |
def shutdown_instance(vm): |
128 | 152 |
start_action(vm, 'STOP') |
129 |
rapi.ShutdownInstance(vm.backend_id) |
|
153 |
rapi.ShutdownInstance(vm.backend_id, dry_run=settings.TEST)
|
|
130 | 154 |
|
131 | 155 |
|
132 | 156 |
def get_instance_console(vm): |
... | ... | |
143 | 167 |
|
144 | 168 |
def update_status(vm, status): |
145 | 169 |
utils.update_state(vm, status) |
170 |
|
|
171 |
def create_network_link(): |
|
172 |
try: |
|
173 |
last = NetworkLink.objects.order_by('-index')[0] |
|
174 |
index = last.index + 1 |
|
175 |
except IndexError: |
|
176 |
index = 1 |
|
177 |
|
|
178 |
if index <= settings.GANETI_MAX_LINK_NUMBER: |
|
179 |
name = '%s%d' % (settings.GANETI_LINK_PREFIX, index) |
|
180 |
return NetworkLink.objects.create(index=index, name=name, |
|
181 |
available=True) |
|
182 |
# FIXME: Shouldn't something at least be logged here? |
|
183 |
return None # All link slots are filled |
|
184 |
|
|
185 |
|
|
186 |
@transaction.commit_on_success |
|
187 |
def create_network(name, owner): |
|
188 |
try: |
|
189 |
link = NetworkLink.objects.filter(available=True)[0] |
|
190 |
except IndexError: |
|
191 |
link = create_network_link() |
|
192 |
if not link: |
|
193 |
return None |
|
194 |
|
|
195 |
network = Network.objects.create( |
|
196 |
name=name, |
|
197 |
owner=owner, |
|
198 |
state='ACTIVE', |
|
199 |
link=link) |
|
200 |
|
|
201 |
link.network = network |
|
202 |
link.available = False |
|
203 |
link.save() |
|
204 |
|
|
205 |
return network |
|
206 |
|
|
207 |
|
|
208 |
@transaction.commit_on_success |
|
209 |
def delete_network(net): |
|
210 |
link = net.link |
|
211 |
if link.name != settings.GANETI_NULL_LINK: |
|
212 |
link.available = True |
|
213 |
link.network = None |
|
214 |
link.save() |
|
215 |
|
|
216 |
for vm in net.machines.all(): |
|
217 |
disconnect_from_network(vm, net) |
|
218 |
vm.save() |
|
219 |
net.state = 'DELETED' |
|
220 |
net.save() |
|
221 |
|
|
222 |
|
|
223 |
def connect_to_network(vm, net): |
|
224 |
nic = {'mode': 'bridged', 'link': net.link.name} |
|
225 |
rapi.ModifyInstance(vm.backend_id, |
|
226 |
nics=[('add', nic)], |
|
227 |
dry_run=settings.TEST) |
|
228 |
|
|
229 |
|
|
230 |
def disconnect_from_network(vm, net): |
|
231 |
nics = vm.nics.filter(network__public=False).order_by('index') |
|
232 |
new_nics = [nic for nic in nics if nic.network != net] |
|
233 |
if new_nics == nics: |
|
234 |
return # Nothing to remove |
|
235 |
ops = [('remove', {})] |
|
236 |
for i, nic in enumerate(new_nics): |
|
237 |
ops.append((i + 1, { |
|
238 |
'mode': 'bridged', |
|
239 |
'link': nic.network.link.name})) |
|
240 |
rapi.ModifyInstance(vm.backend_id, nics=ops, dry_run=settings.TEST) |
|
241 |
|
Also available in: Unified diff