Added exception handlers and rollbacks to fix any resource lock contension due to failures when calling the Unicorn (Floating IP) API
This commit is contained in:
@@ -50,8 +50,15 @@ class UnicornDriver(object):
|
|||||||
url = CONF.QUARK.floating_ip_base_url
|
url = CONF.QUARK.floating_ip_base_url
|
||||||
req = self._build_request_body(floating_ip, port, fixed_ip)
|
req = self._build_request_body(floating_ip, port, fixed_ip)
|
||||||
|
|
||||||
LOG.info("Calling unicorn to register floating ip: %s %s" % (url, req))
|
try:
|
||||||
r = requests.post(url, data=json.dumps(req))
|
LOG.info("Calling unicorn to register floating ip: %s %s"
|
||||||
|
% (url, req))
|
||||||
|
r = requests.post(url, data=json.dumps(req))
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error("Unhandled Exception caught when trying to register "
|
||||||
|
"floating ip %s with the unicorn API. Error: %s"
|
||||||
|
% (floating_ip.id, e.message))
|
||||||
|
raise ex.RegisterFloatingIpFailure(id=floating_ip.id)
|
||||||
|
|
||||||
if r.status_code != 200 and r.status_code != 201:
|
if r.status_code != 200 and r.status_code != 201:
|
||||||
msg = "Unexpected status from unicorn API: Status Code %s, " \
|
msg = "Unexpected status from unicorn API: Status Code %s, " \
|
||||||
@@ -64,8 +71,15 @@ class UnicornDriver(object):
|
|||||||
floating_ip["address_readable"])
|
floating_ip["address_readable"])
|
||||||
req = self._build_request_body(floating_ip, port, fixed_ip)
|
req = self._build_request_body(floating_ip, port, fixed_ip)
|
||||||
|
|
||||||
LOG.info("Calling unicorn to register floating ip: %s %s" % (url, req))
|
try:
|
||||||
r = requests.put(url, data=json.dumps(req))
|
LOG.info("Calling unicorn to register floating ip: %s %s"
|
||||||
|
% (url, req))
|
||||||
|
r = requests.put(url, data=json.dumps(req))
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error("Unhandled Exception caught when trying to update "
|
||||||
|
"floating ip %s with the unicorn API. Error: %s"
|
||||||
|
% (floating_ip.id, e.message))
|
||||||
|
raise ex.RegisterFloatingIpFailure(id=floating_ip.id)
|
||||||
|
|
||||||
if r.status_code != 200 and r.status_code != 201:
|
if r.status_code != 200 and r.status_code != 201:
|
||||||
msg = "Unexpected status from unicorn API: Status Code %s, " \
|
msg = "Unexpected status from unicorn API: Status Code %s, " \
|
||||||
@@ -77,8 +91,14 @@ class UnicornDriver(object):
|
|||||||
url = "%s/%s" % (CONF.QUARK.floating_ip_base_url,
|
url = "%s/%s" % (CONF.QUARK.floating_ip_base_url,
|
||||||
floating_ip.address_readable)
|
floating_ip.address_readable)
|
||||||
|
|
||||||
LOG.info("Calling unicorn to remove floating ip: %s" % url)
|
try:
|
||||||
r = requests.delete(url)
|
LOG.info("Calling unicorn to remove floating ip: %s" % url)
|
||||||
|
r = requests.delete(url)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error("Unhandled Exception caught when trying to un-register "
|
||||||
|
"floating ip %s with the unicorn API. Error: %s"
|
||||||
|
% (floating_ip.id, e.message))
|
||||||
|
raise ex.RemoveFloatingIpFailure(id=floating_ip.id)
|
||||||
|
|
||||||
if r.status_code == 404:
|
if r.status_code == 404:
|
||||||
LOG.warn("The floating IP %s does not exist in the unicorn system."
|
LOG.warn("The floating IP %s does not exist in the unicorn system."
|
||||||
|
|||||||
@@ -125,7 +125,8 @@ def create_floatingip(context, content):
|
|||||||
flip = new_addresses[0]
|
flip = new_addresses[0]
|
||||||
|
|
||||||
if fixed_ip and port:
|
if fixed_ip and port:
|
||||||
with context.session.begin():
|
context.session.begin()
|
||||||
|
try:
|
||||||
flip = db_api.port_associate_ip(context, [port], flip, [port_id])
|
flip = db_api.port_associate_ip(context, [port], flip, [port_id])
|
||||||
flip = db_api.floating_ip_associate_fixed_ip(context, flip,
|
flip = db_api.floating_ip_associate_fixed_ip(context, flip,
|
||||||
fixed_ip)
|
fixed_ip)
|
||||||
@@ -133,6 +134,10 @@ def create_floatingip(context, content):
|
|||||||
flip_driver = registry.DRIVER_REGISTRY.get_driver()
|
flip_driver = registry.DRIVER_REGISTRY.get_driver()
|
||||||
|
|
||||||
flip_driver.register_floating_ip(flip, port, fixed_ip)
|
flip_driver.register_floating_ip(flip, port, fixed_ip)
|
||||||
|
context.session.commit()
|
||||||
|
except Exception:
|
||||||
|
context.session.rollback()
|
||||||
|
raise
|
||||||
|
|
||||||
return v._make_floating_ip_dict(flip, port_id)
|
return v._make_floating_ip_dict(flip, port_id)
|
||||||
|
|
||||||
@@ -164,7 +169,8 @@ def update_floatingip(context, id, content):
|
|||||||
fixed_ip = None
|
fixed_ip = None
|
||||||
current_port = None
|
current_port = None
|
||||||
|
|
||||||
with context.session.begin():
|
context.session.begin()
|
||||||
|
try:
|
||||||
flip = db_api.floating_ip_find(context, id=id, scope=db_api.ONE)
|
flip = db_api.floating_ip_find(context, id=id, scope=db_api.ONE)
|
||||||
if not flip:
|
if not flip:
|
||||||
raise qex.FloatingIpNotFound(id=id)
|
raise qex.FloatingIpNotFound(id=id)
|
||||||
@@ -207,6 +213,7 @@ def update_floatingip(context, id, content):
|
|||||||
flip = db_api.port_associate_ip(context, [port], flip, [port_id])
|
flip = db_api.port_associate_ip(context, [port], flip, [port_id])
|
||||||
flip = db_api.floating_ip_associate_fixed_ip(context, flip,
|
flip = db_api.floating_ip_associate_fixed_ip(context, flip,
|
||||||
fixed_ip)
|
fixed_ip)
|
||||||
|
|
||||||
flip_driver = registry.DRIVER_REGISTRY.get_driver()
|
flip_driver = registry.DRIVER_REGISTRY.get_driver()
|
||||||
|
|
||||||
if port:
|
if port:
|
||||||
@@ -217,6 +224,11 @@ def update_floatingip(context, id, content):
|
|||||||
else:
|
else:
|
||||||
flip_driver.remove_floating_ip(flip)
|
flip_driver.remove_floating_ip(flip)
|
||||||
|
|
||||||
|
context.session.commit()
|
||||||
|
except (qex.RegisterFloatingIpFailure, qex.RemoveFloatingIpFailure):
|
||||||
|
context.session.rollback()
|
||||||
|
raise
|
||||||
|
|
||||||
# Note(alanquillin) The ports parameters on the model is not
|
# Note(alanquillin) The ports parameters on the model is not
|
||||||
# properly getting cleaned up when removed. Manually cleaning them up.
|
# properly getting cleaned up when removed. Manually cleaning them up.
|
||||||
# Need to fix the db api to correctly update the model.
|
# Need to fix the db api to correctly update the model.
|
||||||
@@ -247,7 +259,8 @@ def delete_floatingip(context, id):
|
|||||||
if current_ports and len(current_ports) > 0:
|
if current_ports and len(current_ports) > 0:
|
||||||
current_port = current_ports[0]
|
current_port = current_ports[0]
|
||||||
|
|
||||||
with context.session.begin():
|
context.session.begin()
|
||||||
|
try:
|
||||||
strategy_name = flip.network.get('ipam_strategy')
|
strategy_name = flip.network.get('ipam_strategy')
|
||||||
ipam_driver = ipam.IPAM_REGISTRY.get_strategy(strategy_name)
|
ipam_driver = ipam.IPAM_REGISTRY.get_strategy(strategy_name)
|
||||||
ipam_driver.deallocate_ip_address(context, flip)
|
ipam_driver.deallocate_ip_address(context, flip)
|
||||||
@@ -260,9 +273,13 @@ def delete_floatingip(context, id):
|
|||||||
|
|
||||||
db_api.ip_address_deallocate(context, flip)
|
db_api.ip_address_deallocate(context, flip)
|
||||||
|
|
||||||
if flip.fixed_ip:
|
if flip.fixed_ip:
|
||||||
driver = registry.DRIVER_REGISTRY.get_driver()
|
driver = registry.DRIVER_REGISTRY.get_driver()
|
||||||
driver.remove_floating_ip(flip)
|
driver.remove_floating_ip(flip)
|
||||||
|
context.session.commit()
|
||||||
|
except Exception:
|
||||||
|
context.session.rollback()
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
def get_floatingip(context, id, fields=None):
|
def get_floatingip(context, id, fields=None):
|
||||||
|
|||||||
Reference in New Issue
Block a user