Revision 41a7fae7 snf-cyclades-app/synnefo/quotas/__init__.py
b/snf-cyclades-app/synnefo/quotas/__init__.py | ||
---|---|---|
46 | 46 |
RESOURCES = [ |
47 | 47 |
"cyclades.vm", |
48 | 48 |
"cyclades.cpu", |
49 |
"cyclades.active_cpu", |
|
49 | 50 |
"cyclades.disk", |
50 | 51 |
"cyclades.ram", |
52 |
"cyclades.active_ram", |
|
51 | 53 |
"cyclades.network.private" |
52 | 54 |
] |
53 | 55 |
|
... | ... | |
107 | 109 |
raise Exception("No serial") |
108 | 110 |
|
109 | 111 |
|
112 |
def accept_serial(serial, strict=True): |
|
113 |
response = resolve_commissions(accept=[serial.serial], strict=strict) |
|
114 |
serial.accept = True |
|
115 |
serial.resolved = True |
|
116 |
serial.save() |
|
117 |
return response |
|
118 |
|
|
119 |
|
|
120 |
def reject_serial(serial, strict=True): |
|
121 |
response = resolve_commissions(reject=[serial.serial], strict=strict) |
|
122 |
serial.reject = True |
|
123 |
serial.resolved = True |
|
124 |
serial.save() |
|
125 |
return response |
|
126 |
|
|
127 |
|
|
110 | 128 |
def accept_commissions(accepted, strict=True): |
111 | 129 |
return resolve_commissions(accept=accepted, strict=strict) |
112 | 130 |
|
... | ... | |
222 | 240 |
" '%s' is still pending." % (resource, previous_serial) |
223 | 241 |
raise Exception(msg) |
224 | 242 |
elif previous_serial.accept: |
225 |
accept_commissions(accepted=[previous_serial.serial], strict=False)
|
|
243 |
accept_serial(previous_serial, strict=False)
|
|
226 | 244 |
else: |
227 |
reject_commissions(rejected=[previous_serial.serial], strict=False) |
|
228 |
previous_serial.resolved = True |
|
245 |
reject_serial(previous_serial, strict=False) |
|
229 | 246 |
|
230 | 247 |
try: |
231 | 248 |
# Convert resources in the format expected by Quotaholder |
... | ... | |
241 | 258 |
raise |
242 | 259 |
|
243 | 260 |
try: |
244 |
# Mark the serial as one to accept. This step is necessary for |
|
245 |
# reconciliation |
|
261 |
# Mark the serial as one to accept and associate it with the resource |
|
246 | 262 |
serial.pending = False |
247 | 263 |
serial.accept = True |
248 | 264 |
serial.save() |
249 |
|
|
250 |
# Associate serial with the resource |
|
251 | 265 |
resource.serial = serial |
252 | 266 |
resource.save() |
253 |
|
|
254 |
# Commit transaction in the DB! If this commit succeeds, then the |
|
255 |
# serial is created in the DB with all the necessary information to |
|
256 |
# reconcile commission |
|
257 | 267 |
transaction.commit() |
268 |
# Accept the commission to quotaholder |
|
269 |
accept_serial(serial) |
|
270 |
transaction.commit() |
|
271 |
return serial |
|
258 | 272 |
except: |
273 |
log.exception("Unexpected ERROR") |
|
259 | 274 |
transaction.rollback() |
260 |
serial.pending = False |
|
261 |
serial.accept = False |
|
262 |
serial.save() |
|
275 |
reject_serial(serial) |
|
263 | 276 |
transaction.commit() |
264 | 277 |
raise |
265 | 278 |
|
266 |
if serial.accept: |
|
267 |
# Accept commission to Quotaholder |
|
268 |
accept_commissions(accepted=[serial.serial]) |
|
269 |
else: |
|
270 |
reject_commissions(rejected=[serial.serial]) |
|
271 |
|
|
272 |
# Mark the serial as resolved, indicating that no further actions are |
|
273 |
# needed for this serial |
|
274 |
serial.resolved = True |
|
275 |
serial.save() |
|
276 |
transaction.commit() |
|
277 |
|
|
278 |
return serial |
|
279 |
|
|
280 | 279 |
|
281 | 280 |
def prepare_qh_resources(resource): |
282 | 281 |
if isinstance(resource, VirtualMachine): |
283 | 282 |
flavor = resource.flavor |
284 | 283 |
return {'cyclades.vm': 1, |
285 | 284 |
'cyclades.cpu': flavor.cpu, |
285 |
'cyclades.active_cpu': flavor.cpu, |
|
286 | 286 |
'cyclades.disk': 1073741824 * flavor.disk, # flavor.disk in GB |
287 | 287 |
# 'public_ip': 1, |
288 | 288 |
#'disk_template': flavor.disk_template, |
289 |
'cyclades.ram': 1048576 * flavor.ram} # flavor.ram is in MB |
|
289 |
# flavor.ram is in MB |
|
290 |
'cyclades.ram': 1048576 * flavor.ram, |
|
291 |
'cyclades.active_ram': 1048576 * flavor.ram} |
|
290 | 292 |
elif isinstance(resource, Network): |
291 | 293 |
return {"cyclades.network.private": 1} |
292 | 294 |
else: |
293 | 295 |
raise ValueError("Unknown Resource '%s'" % resource) |
294 | 296 |
|
295 | 297 |
|
298 |
def get_commission_info(resource, action, action_fields=None): |
|
299 |
if isinstance(resource, VirtualMachine): |
|
300 |
flavor = resource.flavor |
|
301 |
resources = {"cyclades.vm": 1, |
|
302 |
"cyclades.cpu": flavor.cpu, |
|
303 |
"cyclades.disk": 1073741824 * flavor.disk, |
|
304 |
"cyclades.ram": 1048576 * flavor.ram} |
|
305 |
online_resources = {"cyclades.active_cpu": flavor.cpu, |
|
306 |
"cyclades.active_ram": 1048576 * flavor.ram} |
|
307 |
# No commission for build! Commission has already been issued and |
|
308 |
# accepted, since the VM has been created in DB. |
|
309 |
#if action == "BUILD": |
|
310 |
# resources.update(online_resources) |
|
311 |
# return resources |
|
312 |
if action == "START": |
|
313 |
if resource.operstate == "STOPPED": |
|
314 |
return online_resources |
|
315 |
else: |
|
316 |
return None |
|
317 |
elif action == "STOP": |
|
318 |
if resource.operstate in ["STARTED", "BUILD", "ERROR"]: |
|
319 |
return reverse_quantities(online_resources) |
|
320 |
else: |
|
321 |
return None |
|
322 |
elif action == "REBOOT": |
|
323 |
if resource.operstate == "STOPPED": |
|
324 |
return online_resources |
|
325 |
else: |
|
326 |
return None |
|
327 |
elif action == "DESTROY": |
|
328 |
if resource.operstate in ["STARTED", "BUILD", "ERROR"]: |
|
329 |
resources.update(online_resources) |
|
330 |
return reverse_quantities(resources) |
|
331 |
elif action == "RESIZE" and action_fields: |
|
332 |
beparams = action_fields.get("beparams") |
|
333 |
cpu = beparams.get("vcpus", flavor.cpu) |
|
334 |
ram = beparams.get("maxmem", flavor.ram) |
|
335 |
return {"cyclades.cpu": cpu - flavor.cpu, |
|
336 |
"cyclades.ram": 1048576 * (ram - flavor.ram)} |
|
337 |
else: |
|
338 |
#["CONNECT", "DISCONNECT", "SET_FIREWALL_PROFILE"]: |
|
339 |
return None |
|
340 |
|
|
341 |
|
|
296 | 342 |
def reverse_quantities(resources): |
297 | 343 |
return dict((r, -s) for r, s in resources.items()) |
344 |
|
|
345 |
|
|
346 |
def resolve_vm_commission(serial): |
|
347 |
log.warning("Resolving pending commission: %s", serial) |
|
348 |
if not serial.pending and serial.accept: |
|
349 |
accept_serial(serial) |
|
350 |
else: |
|
351 |
reject_serial(serial) |
Also available in: Unified diff