contrail-charms: determine vhost0 gateway for multi-interface setup
Affects | Status | Importance | Assigned to | Milestone | ||
---|---|---|---|---|---|---|
Juniper Openstack | Status tracked in Trunk | |||||
R4.1 |
Fix Committed
|
Critical
|
tikitavi | |||
R5.0 |
Fix Committed
|
Critical
|
tikitavi | |||
Trunk |
Fix Committed
|
Critical
|
tikitavi |
Bug Description
currently, the contrail-charms for Contrail 4.1 use the default gateway when charm parameter vhost-gateway is set to auto. This is not feasible for a multi-interface setup where all routes should be checked for valid gateways for the specified vrouter interface.
Default GW only is checked for getting gw IP address:
https:/
https:/
instead of checking the default GW, the function could do somthing like the below to check all installed routes:
def _get_iface_
for line in check_output(
l = line.split()
if "G" in l[3] and ( l[7] == VROUTER_INTERFACE or l[7] == iface ):
return l[1]
log("No gateway could be determined from routing table")
return None
Also, the same routes have to be installed on vhost0 as were present for the original vrouter interface before vhost0 installation. As this depends on the host configuration it might be difficult to consider all possibilities for a persitent configuration but the routes should be installed at least for the provisioning to work.
Changed in juniperopenstack: | |
assignee: | nobody → Andrey Pavlov (apavlov-e) |
to solve vourter provisioning in a multi-interface setup with specific routes I did the following hacks which leads to a working vrouter:
--- ../contrail_ agent_utils. py.orig 2018-06-13 12:11:10.645817961 +0000 charms/ contrail- agent/hooks/ contrail_ agent_utils. py 2018-06-15 12:22:05.564341326 +0000
+++ contrail-
@@ -102,12 +102,33 @@
def _get_iface_ gateway_ ip(iface) : gateways( )["default" ][netifaces. AF_INET] ["route" , "-n"]). splitlines( )[2:]: ["route" , "-n"]). splitlines( )[2:]: append( route) routes) : route[0] , route[2], route[1], str(e)))
- if hasattr(netifaces, "gateways"):
- data = netifaces.
- return data[0] if data[1] == iface else None
-
- data = check_output("ip route | grep ^default", shell=True).split()
- return data[2] if data[4] == iface else None
+ for line in check_output(
+ l = line.split()
+ if "G" in l[3] and ( l[7] == VROUTER_INTERFACE or l[7] == iface ):
+ log("Found gateway {} for interface {}".format(l[1], l[7]))
+ return l[1]
+ log("No gateway could be determined from routing table")
+ return None
+
+
+def _get_routes(iface):
+ routes = []
+ for line in check_output(
+ route = []
+ l = line.split()
+ if "G" in l[3] and ( l[7] == VROUTER_INTERFACE or l[7] == iface ):
+ log("Found route {} {} via gw {} for interface {}".format(l[0], l[2], l[1], l[7]))
+ route = [ l[0], l[1], l[2] ]
+ routes.
+ return routes
+
+def _set_routes(
+ for route in routes:
+ args = [ "route", "add", "-net", route[0], "netmask", route[2], "gw", route[1] ]
+ try:
+ check_call(args)
+ except Exception as e:
+ log("Could not add route {} {} via {}, error: {}".format(
def _vhost_cidr(iface): gateway_ ip(iface) "vhost- gateway- ip"] = gateway_ip
@@ -139,6 +160,8 @@
gateway_ip = _get_iface_
config[
+ routes = _get_routes(iface) realpath( "/sys/class/ net/" + iface).split("/")
render( "agent_ param", "/etc/contrail/ agent_param" ,
{"interface" : iface})
+
if config["dpdk"]:
fs = os.path.
# NOTE: why it's not an error?
@@ -154,6 +177,8 @@
+ _set_routes(routes)
+
def drop_caches():
config. get("api_ port") get("api_ ip") or config. get("api_ vip")) get("analytics_ servers" ) "cloud_ orchestrator" )) get("analytics_ servers" )) get("vrouter- expected- provision- state") : get("vrouter- provisioned" ):
"""Clears OS pagecache"""
@@ -184,8 +209,7 @@
ready = (
and (config.
- and config.
- and info.get(
+ and config.
if config.
if ready and not config.
try: