Commit e9b3acd4 authored by Christos Stavrakakis's avatar Christos Stavrakakis
Browse files

Issue commissions when creating server/networks

Issue commissions to the Quotaholder when creating a VM or a Network.
The VM/Network that is associated with the corresponding serial in DB.
Also, the serial is marked as accepted because at the end of the
transaction the resource will be present in the DB. Even in case the
resource will not be successfully created in the Ganeti, the user has to
explicitly delete it, in order to deallocate the resources.
parent 657a21cc
......@@ -46,6 +46,7 @@ from synnefo.api.actions import network_actions
from synnefo.api.common import method_not_allowed
from synnefo.api.faults import (ServiceUnavailable, BadRequest, Forbidden,
NetworkInUse, OverLimit)
from synnefo import quotas
from synnefo.db.models import Network
from synnefo.db.pools import EmptyPool
from synnefo.logic import backend
......@@ -145,8 +146,9 @@ def list_networks(request, detail=False):
@util.api_method('POST')
@quotas.uses_commission
@transaction.commit_on_success
def create_network(request):
def create_network(serials, request):
# Normal Response Code: 202
# Error Response Codes: computeFault (400, 500),
# serviceUnavailable (503),
......@@ -183,20 +185,18 @@ def create_network(request):
if net_type not in settings.ENABLED_NETWORKS:
raise Forbidden("Can not create %s network" % net_type)
networks_user_limit = \
settings.NETWORKS_USER_QUOTA.get(request.user_uniq,
settings.MAX_NETWORKS_PER_USER)
user_networks = len(Network.objects.filter(userid=request.user_uniq,
deleted=False))
if user_networks >= networks_user_limit:
raise OverLimit('Network count limit exceeded for your account.')
cidr_block = int(subnet.split('/')[1])
if not util.validate_network_size(cidr_block):
raise OverLimit("Unsupported network size.")
user_id = request.user_uniq
serial = quotas.issue_network_commission(user_id)
serials.append(serial)
# Make the commission accepted, since in the end of this
# transaction the Network will have been created in the DB.
serial.accepted = True
serial.save()
try:
link, mac_prefix = util.net_resources(net_type)
if not link:
......@@ -204,7 +204,7 @@ def create_network(request):
network = Network.objects.create(
name=name,
userid=request.user_uniq,
userid=user_id,
subnet=subnet,
subnet6=subnet6,
gateway=gateway,
......@@ -214,7 +214,8 @@ def create_network(request):
link=link,
mac_prefix=mac_prefix,
action='CREATE',
state='PENDING')
state='PENDING',
serial=serial)
except EmptyPool:
log.error("Failed to allocate resources for network of type: %s",
net_type)
......@@ -227,7 +228,9 @@ def create_network(request):
backend.create_network(network)
networkdict = network_to_dict(network, request.user_uniq)
return render_network(request, networkdict, status=202)
response = render_network(request, networkdict, status=202)
return response
@util.api_method('GET')
......
......@@ -46,6 +46,7 @@ from synnefo.logic.backend import create_instance, delete_instance
from synnefo.logic.utils import get_rsapi_state
from synnefo.logic.rapi import GanetiApiError
from synnefo.logic.backend_allocator import BackendAllocator
from synnefo import quotas
from logging import getLogger
......@@ -241,8 +242,9 @@ def list_servers(request, detail=False):
# access (SELECT..FOR UPDATE). Running create_server with commit_on_success
# would result in backends and public networks to be locked until the job is
# sent to the Ganeti backend.
@quotas.uses_commission
@transaction.commit_manually
def create_server(request):
def create_server(serials, request):
# Normal Response Code: 202
# Error Response Codes: computeFault (400, 500),
# serviceUnavailable (503),
......@@ -277,17 +279,6 @@ def create_server(request):
flavor = util.get_flavor(flavor_id)
password = util.random_password()
count = VirtualMachine.objects.filter(userid=user_id,
deleted=False).count()
# get user limit
vms_limit_for_user = \
settings.VMS_USER_QUOTA.get(user_id,
settings.MAX_VMS_PER_USER)
if count >= vms_limit_for_user:
raise faults.OverLimit("Server count limit exceeded for your account.")
backend_allocator = BackendAllocator()
backend = backend_allocator.allocate(request.user_uniq, flavor)
......@@ -309,6 +300,14 @@ def create_server(request):
transaction.commit()
try:
# Issue commission
serial = quotas.issue_vm_commission(user_id, flavor)
serials.append(serial)
# Make the commission accepted, since in the end of this
# transaction the VM will have been created in the DB.
serial.accepted = True
serial.save()
# We must save the VM instance now, so that it gets a valid
# vm.backend_vm_id.
vm = VirtualMachine.objects.create(
......@@ -317,7 +316,8 @@ def create_server(request):
userid=user_id,
imageid=image_id,
flavor=flavor,
action="CREATE")
action="CREATE",
serial=serial)
try:
jobID = create_instance(vm, nic, flavor, image, password,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment