Revision dca7553e snf-cyclades-app/synnefo/api/servers.py
b/snf-cyclades-app/synnefo/api/servers.py | ||
---|---|---|
31 | 31 |
# interpreted as representing official policies, either expressed |
32 | 32 |
# or implied, of GRNET S.A. |
33 | 33 |
|
34 |
from base64 import b64decode |
|
35 |
|
|
36 | 34 |
from django.conf import settings |
37 | 35 |
from django.conf.urls.defaults import patterns |
38 | 36 |
from django.db import transaction |
... | ... | |
48 | 46 |
from synnefo.logic.utils import get_rsapi_state |
49 | 47 |
from synnefo.logic.rapi import GanetiApiError |
50 | 48 |
from synnefo.logic.backend_allocator import BackendAllocator |
51 |
from random import choice |
|
52 | 49 |
|
53 | 50 |
|
54 | 51 |
from logging import getLogger |
... | ... | |
258 | 255 |
try: |
259 | 256 |
req = util.get_request_dict(request) |
260 | 257 |
log.info('create_server %s', req) |
258 |
user_id = request.user_uniq |
|
261 | 259 |
|
262 | 260 |
try: |
263 | 261 |
server = req['server'] |
... | ... | |
274 | 272 |
if len(personality) > settings.MAX_PERSONALITY: |
275 | 273 |
raise faults.OverLimit("Maximum number of personalities exceeded") |
276 | 274 |
|
277 |
for p in personality: |
|
278 |
# Verify that personalities are well-formed |
|
279 |
try: |
|
280 |
assert isinstance(p, dict) |
|
281 |
keys = set(p.keys()) |
|
282 |
allowed = set(['contents', 'group', 'mode', 'owner', 'path']) |
|
283 |
assert keys.issubset(allowed) |
|
284 |
contents = p['contents'] |
|
285 |
if len(contents) > settings.MAX_PERSONALITY_SIZE: |
|
286 |
# No need to decode if contents already exceed limit |
|
287 |
raise faults.OverLimit("Maximum size of personality exceeded") |
|
288 |
if len(b64decode(contents)) > settings.MAX_PERSONALITY_SIZE: |
|
289 |
raise faults.OverLimit("Maximum size of personality exceeded") |
|
290 |
except AssertionError: |
|
291 |
raise faults.BadRequest("Malformed personality in request") |
|
292 |
|
|
293 |
image = {} |
|
294 |
img = util.get_image(image_id, request.user_uniq) |
|
295 |
properties = img.get('properties', {}) |
|
296 |
image['backend_id'] = img['location'] |
|
297 |
image['format'] = img['disk_format'] |
|
298 |
image['metadata'] = dict((key.upper(), val) \ |
|
299 |
for key, val in properties.items()) |
|
300 |
|
|
301 |
# Ensure that request if for active flavor |
|
302 |
flavor = util.get_flavor(flavor_id, include_deleted=False) |
|
275 |
util.verify_personality(personality) |
|
276 |
image = util.get_image_dict(image_id, user_id) |
|
277 |
flavor = util.get_flavor(flavor_id) |
|
303 | 278 |
password = util.random_password() |
304 | 279 |
|
305 |
count = VirtualMachine.objects.filter(userid=request.user_uniq,
|
|
280 |
count = VirtualMachine.objects.filter(userid=user_id,
|
|
306 | 281 |
deleted=False).count() |
307 | 282 |
|
308 | 283 |
# get user limit |
309 | 284 |
vms_limit_for_user = \ |
310 |
settings.VMS_USER_QUOTA.get(request.user_uniq,
|
|
285 |
settings.VMS_USER_QUOTA.get(user_id,
|
|
311 | 286 |
settings.MAX_VMS_PER_USER) |
312 | 287 |
|
313 | 288 |
if count >= vms_limit_for_user: |
... | ... | |
326 | 301 |
transaction.commit() |
327 | 302 |
|
328 | 303 |
try: |
329 |
if settings.PUBLIC_USE_POOL: |
|
330 |
(network, address) = util.allocate_public_address(backend) |
|
331 |
if address is None: |
|
332 |
log.error("Public networks of backend %s are full", backend) |
|
333 |
msg = "Failed to allocate public IP for new VM" |
|
334 |
raise faults.ServiceUnavailable(msg) |
|
335 |
nic = {'ip': address, 'network': network.backend_id} |
|
336 |
else: |
|
337 |
network = choice(list(util.backend_public_networks(backend))) |
|
338 |
nic = {'ip': 'pool', 'network': network.backend_id} |
|
304 |
(network, address) = util.get_public_ip(backend) |
|
305 |
nic = {'ip': address, 'network': network.backend_id} |
|
339 | 306 |
except: |
340 | 307 |
transaction.rollback() |
341 |
raise |
|
342 | 308 |
else: |
343 | 309 |
transaction.commit() |
344 | 310 |
|
... | ... | |
348 | 314 |
vm = VirtualMachine.objects.create( |
349 | 315 |
name=name, |
350 | 316 |
backend=backend, |
351 |
userid=request.user_uniq,
|
|
317 |
userid=user_id,
|
|
352 | 318 |
imageid=image_id, |
353 | 319 |
flavor=flavor, |
354 | 320 |
action="CREATE") |
355 | 321 |
|
356 | 322 |
try: |
357 |
jobID = create_instance(vm, nic, flavor, image, password, personality) |
|
323 |
jobID = create_instance(vm, nic, flavor, image, password, |
|
324 |
personality) |
|
358 | 325 |
except GanetiApiError: |
359 | 326 |
vm.delete() |
360 | 327 |
raise |
361 | 328 |
|
362 | 329 |
log.info("User %s created VM %s, NIC %s, Backend %s, JobID %s", |
363 |
request.user_uniq, vm, nic, backend, str(jobID))
|
|
330 |
user_id, vm, nic, backend, str(jobID))
|
|
364 | 331 |
|
365 | 332 |
vm.backendjobid = jobID |
366 | 333 |
vm.save() |
Also available in: Unified diff