Revision 0c50c760
b/snf-cyclades-app/synnefo/api/floating_ips.py | ||
---|---|---|
138 | 138 |
network, address = util.get_free_ip(net_objects) |
139 | 139 |
else: |
140 | 140 |
try: |
141 |
network = Network.objects.select_for_update()\ |
|
142 |
.get(id=pool, public=True, |
|
143 |
deleted=False, |
|
144 |
floating_ip_pool=True) |
|
145 |
|
|
146 |
except Network.DoesNotExist: |
|
141 |
network_id = int(pool) |
|
142 |
except ValueErrorx: |
|
143 |
raise faults.BadRequest("Invalid pool ID.") |
|
144 |
network = next((n for n in net_objects if n.id==pool), None) |
|
145 |
if network is None: |
|
147 | 146 |
raise faults.ItemNotFound("Pool '%s' does not exist." % pool) |
148 | 147 |
if address is None: |
149 | 148 |
# User did not specified an IP address. Choose a random one |
b/snf-cyclades-app/synnefo/db/models.py | ||
---|---|---|
708 | 708 |
(self.index, self.machine_id, self.network_id, self.ipv4, |
709 | 709 |
self.ipv6) |
710 | 710 |
|
711 |
@property |
|
712 |
def is_floating_ip(self): |
|
713 |
network = self.network |
|
714 |
if self.ipv4 and network.floating_ip_pool: |
|
715 |
return network.floating_ips.filter(machine=self.machine, |
|
716 |
ipv4=self.ipv4, |
|
717 |
deleted=False).exists() |
|
718 |
return False |
|
719 |
|
|
711 | 720 |
|
712 | 721 |
class FloatingIP(models.Model): |
713 | 722 |
userid = models.CharField("UUID of the owner", max_length=128, |
b/snf-cyclades-app/synnefo/logic/backend.py | ||
---|---|---|
300 | 300 |
to_release = old_addresses - new_addresses |
301 | 301 |
for (network_id, ipv4) in to_release: |
302 | 302 |
if ipv4: |
303 |
net = Network.objects.get(id=network_id)
|
|
304 |
# Important: Take exclusive lock in pool before checking if there
|
|
305 |
# is a floating IP with this ipv4 address, otherwise there is a
|
|
306 |
# race condition, where you may release a floating IP that has been
|
|
307 |
# created after search floating IPs and before you get exclusively
|
|
308 |
# the pool
|
|
309 |
pool = net.get_pool()
|
|
310 |
try:
|
|
311 |
floating_ip = net.floating_ips.select_for_update()\
|
|
312 |
.get(ipv4=ipv4, machine=vm,
|
|
313 |
deleted=False)
|
|
314 |
floating_ip.machine = None
|
|
315 |
floating_ip.save()
|
|
316 |
except FloatingIP.DoesNotExist:
|
|
303 |
# Get X-Lock before searching floating IP, to exclusively search
|
|
304 |
# and release floating IP. Otherwise you may release a floating IP
|
|
305 |
# that has been just reserved.
|
|
306 |
net = Network.objects.select_for_update().get(id=network_id)
|
|
307 |
if net.floating_ip_pool:
|
|
308 |
try:
|
|
309 |
floating_ip = net.floating_ips.select_for_update()\
|
|
310 |
.get(ipv4=ipv4, machine=vm,
|
|
311 |
deleted=False)
|
|
312 |
floating_ip.machine = None
|
|
313 |
floating_ip.save()
|
|
314 |
except FloatingIP.DoesNotExist:
|
|
315 |
net.release_address(ipv4)
|
|
316 |
else:
|
|
317 | 317 |
net.release_address(ipv4) |
318 |
pool.save() |
|
319 | 318 |
|
320 | 319 |
|
321 | 320 |
@transaction.commit_on_success |
b/snf-cyclades-app/synnefo/logic/tests.py | ||
---|---|---|
268 | 268 |
self.assertFalse(db_vm.nics.all()) |
269 | 269 |
self.assertTrue(nic.network.get_pool().is_available(nic.ipv4)) |
270 | 270 |
vm2 = mfactory.VirtualMachineFactory() |
271 |
network = mfactory.NetworkFactory() |
|
271 |
network = mfactory.NetworkFactory(floating_ip_pool=True)
|
|
272 | 272 |
fp1 = mfactory.FloatingIPFactory(machine=vm2, network=network) |
273 | 273 |
fp2 = mfactory.FloatingIPFactory(machine=vm2, network=network) |
274 | 274 |
mfactory.NetworkInterfaceFactory(machine=vm2, network=network, |
Also available in: Unified diff