From eda92a7cbba1230519361e223e13ddd7788cc907 Mon Sep 17 00:00:00 2001 From: Joshua Boniface Date: Mon, 24 Sep 2018 03:20:46 -0400 Subject: [PATCH] Fix a few more bugs with master selection --- router-daemon/pvcrd/Daemon.py | 13 +++++-- router-daemon/pvcrd/RouterInstance.py | 47 +++++++++++++----------- router-daemon/pvcrd/VXNetworkInstance.py | 8 ++-- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/router-daemon/pvcrd/Daemon.py b/router-daemon/pvcrd/Daemon.py index 075d8a9a..e859e1a3 100644 --- a/router-daemon/pvcrd/Daemon.py +++ b/router-daemon/pvcrd/Daemon.py @@ -210,12 +210,17 @@ def updaterouters(new_router_list): else: t_router[router] = RouterInstance.RouterInstance(myhostname, router, t_router, s_network, zk_conn, config) +# Set up our update function +this_router = t_router[myhostname] +update_zookeeper = this_router.update_zookeeper +update_zookeeper() + @zk_conn.ChildrenWatch('/networks') def updatenetworks(new_network_list): global network_list for network in new_network_list: if not network in s_network: - s_network[network] = VXNetworkInstance.VXNetworkInstance(network, zk_conn, config, t_router[myhostname]); + s_network[network] = VXNetworkInstance.VXNetworkInstance(network, zk_conn, config, t_router[myhostname]) if not network in new_network_list: s_network[network].removeAddress() s_network[network].removeNetwork() @@ -225,9 +230,9 @@ def updatenetworks(new_network_list): network_list = new_network_list print(ansiiprint.blue() + 'Network list: ' + ansiiprint.end() + '{}'.format(' '.join(network_list))) -# Set up our update function -this_router = t_router[myhostname] -update_zookeeper = this_router.update_zookeeper +# Ensure we force startup of interfaces if we're primary +if this_router.getnetworkstate() == 'primary': + this_router.become_primary() # Create timer to update this router in Zookeeper def createKeepaliveTimer(): diff --git a/router-daemon/pvcrd/RouterInstance.py b/router-daemon/pvcrd/RouterInstance.py index 7c9ea139..8da4c6c1 100644 --- a/router-daemon/pvcrd/RouterInstance.py +++ b/router-daemon/pvcrd/RouterInstance.py @@ -61,22 +61,17 @@ class RouterInstance(): @zk_conn.DataWatch('/routers/{}/networkstate'.format(self.name)) def watch_hypervisor_networkstate(data, stat, event=""): try: - new_network_state = data.decode('ascii') + self.network_state = data.decode('ascii') except AttributeError: - new_network_state = 'secondary' + self.network_state = 'secondary' - if new_network_state != self.network_state: - self.network_state = new_network_state - # toggle state management of this router + # toggle state management of this router + if s_network != {}: # If there's no network list, we're too early in startup if self.name == self.this_router: if self.network_state == 'secondary': - self.set_secondary() + self.become_secondary() if self.network_state == 'primary': - self.set_primary() - for router in t_router: - if t_router[router].getname() != self.name: - t_router[router].set_secondary() - + self.become_primary() # Get value functions def getname(self): @@ -100,20 +95,30 @@ class RouterInstance(): for network in s_network: self.network_list.append(s_network[network].getvni()) - # Flush all VMs on the host + def become_secondary(self): + ansiiprint.echo('Setting router {} to secondary state'.format(self.name), '', 'i') + ansiiprint.echo('Network list: {}'.format(', '.join(self.network_list)), '', 'c') + for network in self.s_network: + self.s_network[network].removeAddress() + for router in self.t_router: + if self.t_router[router].getname() != self.this_router: + zkhandler.writedata(self.zk_conn, { '/routers/{}/networkstate'.format(self.t_router[router].getname()): 'primary' }) + def set_secondary(self): - ansiiprint.echo('Setting node {} to secondary state'.format(self.name), '', 'i') - ansiiprint.echo('Network list: {}'.format(', '.join(self.network_list)), '', 'c') zkhandler.writedata(self.zk_conn, { '/routers/{}/networkstate'.format(self.name): 'secondary' }) - for network in self.s_network: - network.removeAddress() - - def set_primary(self): - ansiiprint.echo('Setting node {} to master state.'.format(self.name), '', 'i') + + def become_primary(self): + ansiiprint.echo('Setting router {} to primary state.'.format(self.name), '', 'i') ansiiprint.echo('Network list: {}'.format(', '.join(self.network_list)), '', 'c') - zkhandler.writedata(self.zk_conn, { '/routers/{}/networkstate'.format(self.name): 'primary' }) for network in self.s_network: - network.createAddress() + self.s_network[network].createAddress() + for router in self.t_router: + if self.t_router[router].getname() != self.this_router: + zkhandler.writedata(self.zk_conn, { '/routers/{}/networkstate'.format(self.t_router[router].getname()): 'secondary' }) + + def set_primary(self): + zkhandler.writedata(self.zk_conn, { '/routers/{}/networkstate'.format(self.name): 'primary' }) + def update_zookeeper(self): # Get past state and update if needed diff --git a/router-daemon/pvcrd/VXNetworkInstance.py b/router-daemon/pvcrd/VXNetworkInstance.py index bb2d2b98..1b38663d 100644 --- a/router-daemon/pvcrd/VXNetworkInstance.py +++ b/router-daemon/pvcrd/VXNetworkInstance.py @@ -30,10 +30,10 @@ import daemon_lib.common as common class VXNetworkInstance(): # Initialization function - def __init__ (self, vni, zk_conn, config, thisrouter): + def __init__ (self, vni, zk_conn, config, this_router): self.vni = vni self.zk_conn = zk_conn - self.thisrouter = thisrouter + self.this_router = this_router self.vni_dev = config['vni_dev'] self.old_description = zkhandler.readdata(self.zk_conn, '/networks/{}'.format(self.vni)) @@ -88,7 +88,7 @@ class VXNetworkInstance(): def createAddress(self): if self.this_router.getnetworkstate() == 'primary': ansiiprint.echo('Creating gateway {} on interface {}'.format(self.ip_gateway, self.vni_dev), '', 'o') - common.run_os_command('ip address add {}/{} dev {}'.format(self.ip_gateway, self.ip_cidrnetmask, self.vni_dev)) + common.run_os_command('ip address add {}/{} dev {}'.format(self.ip_gateway, self.ip_cidrnetmask, self.bridge_nic)) def removeNetwork(self): ansiiprint.echo('Removing VNI {} device on interface {}'.format(self.vni, self.vni_dev), '', 'o') @@ -100,4 +100,4 @@ class VXNetworkInstance(): def removeAddress(self): ansiiprint.echo('Removing gateway {} from interface {}'.format(self.ip_gateway, self.vni_dev), '', 'o') - common.run_os_command('ip address delete {}/{} dev {}'.format(self.ip_gateway, self.ip_cidrnetmask, self.vni_dev)) + common.run_os_command('ip address delete {}/{} dev {}'.format(self.ip_gateway, self.ip_cidrnetmask, self.bridge_nic))