- while not assigned:
- try:
- # the vim_id key contains the neutron.port_id
- self.neutron.update_floatingip(free_floating_ip,
- {"floatingip": {"port_id": floating_network["vim_id"]}})
- # Using nove is deprecated on nova client 10.0
- assigned = True
- except Exception as e:
- # openstack need some time after VM creation to asign an IP. So retry if fails
- vm_status = self.nova.servers.get(server.id).status
- if vm_status != 'ACTIVE' and vm_status != 'ERROR':
- if time.time() - vm_start_time < server_timeout:
- time.sleep(5)
- continue
- raise vimconn.vimconnException(
- "Cannot create floating_ip: {} {}".format(type(e).__name__, e),
- http_code=vimconn.HTTP_Conflict)
+ try:
+ # for race condition ensure not already assigned
+ fip = self.neutron.show_floatingip(free_floating_ip)
+ if fip['floatingip']['port_id']:
+ continue
+ # the vim_id key contains the neutron.port_id
+ self.neutron.update_floatingip(free_floating_ip,
+ {"floatingip": {"port_id": floating_network["vim_id"]}})
+ # for race condition ensure not re-assigned to other VM after 5 seconds
+ time.sleep(5)
+ fip = self.neutron.show_floatingip(free_floating_ip)
+ if fip['floatingip']['port_id'] != floating_network["vim_id"]:
+ self.logger.error("floating_ip {} re-assigned to other port".format(free_floating_ip))
+ continue
+ self.logger.debug("Assigned floating_ip {} to VM {}".format(free_floating_ip, server.id))
+ assigned = True
+ except Exception as e:
+ # openstack need some time after VM creation to assign an IP. So retry if fails
+ vm_status = self.nova.servers.get(server.id).status
+ if vm_status not in ('ACTIVE', 'ERROR'):
+ if time.time() - vm_start_time < server_timeout:
+ time.sleep(5)
+ continue
+ elif floating_ip_retries > 0:
+ floating_ip_retries -= 1
+ continue
+ raise vimconn.VimConnException(
+ "Cannot create floating_ip: {} {}".format(type(e).__name__, e),
+ http_code=vimconn.HTTP_Conflict)